Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
kyber-k2so
Kyber-K2SO
Commits
bbe6792f
Commit
bbe6792f
authored
Jul 29, 2020
by
Nadim Kobeissi
💾
Browse files
Enforce lengths on byte arrays
parent
9e5adc2a
Changes
8
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
bbe6792f
# SPDX-FileCopyrightText: © 2020-2021 Nadim Kobeissi <nadim@symbolic.software>
# SPDX-License-Identifier: CC0-1.0
# Verifpal
cmd/kyber-r2d2/resource.syso
build/kyber-r2d2.*
dist
# Binaries for programs and plugins
*.exe
*.exe~
...
...
Makefile
View file @
bbe6792f
...
...
@@ -8,7 +8,7 @@ lint:
test
:
@
go clean
-testcache
@
/bin/echo
"[Kyber-K2SO] Running test battery..."
@
go
test
.
/cmd/kyberk2so
@
go
test
.
clean
:
@
/bin/echo
-n
"[Kyber-K2SO] Cleaning up..."
...
...
@@ -16,4 +16,4 @@ clean:
@
$(RM)
-r
dist
@
/bin/echo
" OK"
.PHONY
:
all windows linux macos freebsd lint test release clean assets
build cmd
.PHONY
:
all windows linux macos freebsd lint test release clean assets
byteops.go
View file @
bbe6792f
...
...
@@ -16,7 +16,7 @@ func byteopsCbd(buf []byte) poly {
var
t
,
d
uint32
var
a
,
b
int16
r
:=
polyNew
()
for
i
:=
0
;
i
<
params
.
n
/
8
;
i
++
{
for
i
:=
0
;
i
<
params
N
/
8
;
i
++
{
t
=
byteopsLoad32
(
buf
[
4
*
i
:
(
4
*
i
)
+
4
])
d
=
t
&
0x55555555
d
=
d
+
((
t
>>
1
)
&
0x55555555
)
...
...
@@ -30,8 +30,8 @@ func byteopsCbd(buf []byte) poly {
}
func
byteopsMontgomeryReduce
(
a
int32
)
int16
{
u
:=
int16
(
a
*
int32
(
params
.
q
inv
))
t
:=
int32
(
u
)
*
int32
(
params
.
q
)
u
:=
int16
(
a
*
int32
(
params
Q
inv
))
t
:=
int32
(
u
)
*
int32
(
params
Q
)
t
=
a
-
t
t
>>=
16
return
int16
(
t
)
...
...
@@ -39,14 +39,14 @@ func byteopsMontgomeryReduce(a int32) int16 {
func
byteopsBarrettReduce
(
a
int16
)
int16
{
var
t
int16
var
v
int16
=
int16
(((
uint32
(
1
)
<<
26
)
+
uint32
(
params
.
q
/
2
))
/
uint32
(
params
.
q
))
var
v
int16
=
int16
(((
uint32
(
1
)
<<
26
)
+
uint32
(
params
Q
/
2
))
/
uint32
(
params
Q
))
t
=
int16
(
int32
(
v
)
*
int32
(
a
)
>>
26
)
t
=
t
*
int16
(
params
.
q
)
t
=
t
*
int16
(
params
Q
)
return
a
-
t
}
func
byteopsCSubQ
(
a
int16
)
int16
{
a
=
a
-
int16
(
params
.
q
)
a
=
a
+
((
a
>>
15
)
&
int16
(
params
.
q
))
a
=
a
-
int16
(
params
Q
)
a
=
a
+
((
a
>>
15
)
&
int16
(
params
Q
))
return
a
}
indcpa.go
View file @
bbe6792f
...
...
@@ -14,8 +14,8 @@ func indcpaPackPublicKey(publicKey polyvec, seed []byte) []byte {
}
func
indcpaUnpackPublicKey
(
packedPublicKey
[]
byte
)
(
polyvec
,
[]
byte
)
{
publicKeyPolyvec
:=
polyvecFromBytes
(
packedPublicKey
[
:
params
.
p
olyvec
b
ytes
])
seed
:=
packedPublicKey
[
params
.
p
olyvec
b
ytes
:
]
publicKeyPolyvec
:=
polyvecFromBytes
(
packedPublicKey
[
:
params
P
olyvec
B
ytes
])
seed
:=
packedPublicKey
[
params
P
olyvec
B
ytes
:
]
return
publicKeyPolyvec
,
seed
}
...
...
@@ -32,8 +32,8 @@ func indcpaPackCiphertext(b polyvec, v poly) []byte {
}
func
indcpaUnpackCiphertext
(
c
[]
byte
)
(
polyvec
,
poly
)
{
b
:=
polyvecDecompress
(
c
[
:
params
.
p
olyvec
c
ompressed
b
ytes
])
v
:=
polyDecompress
(
c
[
params
.
p
olyvec
c
ompressed
b
ytes
:
])
b
:=
polyvecDecompress
(
c
[
:
params
P
olyvec
C
ompressed
B
ytes
])
v
:=
polyDecompress
(
c
[
params
P
olyvec
C
ompressed
B
ytes
:
])
return
b
,
v
}
...
...
@@ -45,8 +45,8 @@ func indcpaRejUniform(l int, buf []byte, bufl int) ([]int16, int) {
for
ctr
<
l
&&
pos
+
2
<=
bufl
{
val
=
uint16
(
buf
[
pos
])
|
(
uint16
(
buf
[
pos
+
1
])
<<
8
)
pos
=
pos
+
2
if
val
<
uint16
(
19
*
params
.
q
)
{
val
=
val
-
((
val
>>
12
)
*
uint16
(
params
.
q
))
if
val
<
uint16
(
19
*
params
Q
)
{
val
=
val
-
((
val
>>
12
)
*
uint16
(
params
Q
))
r
[
ctr
]
=
int16
(
val
)
ctr
=
ctr
+
1
}
...
...
@@ -55,13 +55,13 @@ func indcpaRejUniform(l int, buf []byte, bufl int) ([]int16, int) {
}
func
indcpaGenMatrix
(
seed
[]
byte
,
transposed
bool
)
([]
polyvec
,
error
)
{
r
:=
make
([]
polyvec
,
params
.
k
)
r
:=
make
([]
polyvec
,
params
K
)
buf
:=
make
([]
byte
,
4
*
168
)
xof
:=
sha3
.
NewShake128
()
ctr
:=
0
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
r
[
i
]
=
polyvecNew
()
for
j
:=
0
;
j
<
params
.
k
;
j
++
{
for
j
:=
0
;
j
<
params
K
;
j
++
{
transposon
:=
[]
byte
{
byte
(
j
),
byte
(
i
)}
if
transposed
{
transposon
=
[]
byte
{
byte
(
i
),
byte
(
j
)}
...
...
@@ -75,17 +75,17 @@ func indcpaGenMatrix(seed []byte, transposed bool) ([]polyvec, error) {
if
err
!=
nil
{
return
[]
polyvec
{},
err
}
r
[
i
]
.
vec
[
j
]
.
coeffs
,
ctr
=
indcpaRejUniform
(
params
.
n
,
buf
,
len
(
buf
))
for
ctr
<
params
.
n
{
r
[
i
]
.
vec
[
j
]
.
coeffs
,
ctr
=
indcpaRejUniform
(
params
N
,
buf
,
len
(
buf
))
for
ctr
<
params
N
{
bufn
:=
make
([]
byte
,
168
)
_
,
err
=
xof
.
Read
(
bufn
)
if
err
!=
nil
{
return
[]
polyvec
{},
err
}
missing
,
ctrn
:=
indcpaRejUniform
(
params
.
n
-
ctr
,
bufn
,
168
)
missing
,
ctrn
:=
indcpaRejUniform
(
params
N
-
ctr
,
bufn
,
168
)
r
[
i
]
.
vec
[
j
]
.
coeffs
=
append
(
r
[
i
]
.
vec
[
j
]
.
coeffs
[
:
ctr
],
missing
[
:
params
.
n
-
ctr
]
...
,
missing
[
:
params
N
-
ctr
]
...
,
)
ctr
=
ctr
+
ctrn
}
...
...
@@ -104,35 +104,35 @@ func indcpaKeypair() ([]byte, []byte, error) {
skpv
:=
polyvecNew
()
pkpv
:=
polyvecNew
()
e
:=
polyvecNew
()
buf
:=
make
([]
byte
,
2
*
params
.
s
ym
b
ytes
)
buf
:=
make
([]
byte
,
2
*
params
S
ym
B
ytes
)
h
:=
sha3
.
New512
()
_
,
err
:=
rand
.
Read
(
buf
[
:
params
.
s
ym
b
ytes
])
_
,
err
:=
rand
.
Read
(
buf
[
:
params
S
ym
B
ytes
])
if
err
!=
nil
{
return
[]
byte
{},
[]
byte
{},
err
}
_
,
err
=
h
.
Write
(
buf
[
:
params
.
s
ym
b
ytes
])
_
,
err
=
h
.
Write
(
buf
[
:
params
S
ym
B
ytes
])
if
err
!=
nil
{
return
[]
byte
{},
[]
byte
{},
err
}
buf
=
buf
[
:
0
]
buf
=
h
.
Sum
(
buf
)
publicSeed
,
noiseSeed
:=
buf
[
:
params
.
s
ym
b
ytes
],
buf
[
params
.
s
ym
b
ytes
:
]
publicSeed
,
noiseSeed
:=
buf
[
:
params
S
ym
B
ytes
],
buf
[
params
S
ym
B
ytes
:
]
a
,
err
:=
indcpaGenMatrix
(
publicSeed
,
false
)
if
err
!=
nil
{
return
[]
byte
{},
[]
byte
{},
err
}
var
nonce
byte
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
skpv
.
vec
[
i
]
=
polyGetNoise
(
noiseSeed
,
nonce
)
nonce
=
nonce
+
1
}
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
e
.
vec
[
i
]
=
polyGetNoise
(
noiseSeed
,
nonce
)
nonce
=
nonce
+
1
}
skpv
=
polyvecNtt
(
skpv
)
e
=
polyvecNtt
(
e
)
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
pkpv
.
vec
[
i
]
=
polyvecPointWiseAccMontgomery
(
a
[
i
],
skpv
)
pkpv
.
vec
[
i
]
=
polyToMont
(
pkpv
.
vec
[
i
])
}
...
...
@@ -148,21 +148,21 @@ func indcpaEncrypt(m []byte, publicKey []byte, coins []byte) ([]byte, error) {
nonce
:=
byte
(
0
)
publicKeyPolyvec
,
seed
:=
indcpaUnpackPublicKey
(
publicKey
)
k
:=
polyFromMsg
(
m
)
at
,
err
:=
indcpaGenMatrix
(
seed
[
:
params
.
s
ym
b
ytes
],
true
)
at
,
err
:=
indcpaGenMatrix
(
seed
[
:
params
S
ym
B
ytes
],
true
)
if
err
!=
nil
{
return
[]
byte
{},
err
}
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
sp
.
vec
[
i
]
=
polyGetNoise
(
coins
,
nonce
)
nonce
=
nonce
+
1
}
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
ep
.
vec
[
i
]
=
polyGetNoise
(
coins
,
nonce
)
nonce
=
nonce
+
1
}
epp
:=
polyGetNoise
(
coins
,
nonce
)
sp
=
polyvecNtt
(
sp
)
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
bp
.
vec
[
i
]
=
polyvecPointWiseAccMontgomery
(
at
[
i
],
sp
)
}
v
:=
polyvecPointWiseAccMontgomery
(
publicKeyPolyvec
,
sp
)
...
...
kem.go
View file @
bbe6792f
...
...
@@ -15,58 +15,71 @@ import (
// KemKeypair returns a Kyber-768 private key and a corresponding Kyber-768 public key.
// An accompanying error is returned if no sufficient randomness could be obtained from the system.
func
KemKeypair
()
([]
byte
,
[]
byte
,
error
)
{
func
KemKeypair
()
([
paramsSecretKeyBytes
]
byte
,
[
paramsPublicKeyBytes
]
byte
,
error
)
{
var
privateKeyFixedLength
[
paramsSecretKeyBytes
]
byte
var
publicKeyFixedLength
[
paramsPublicKeyBytes
]
byte
indcpaPrivateKey
,
indcpaPublicKey
,
err
:=
indcpaKeypair
()
if
err
!=
nil
{
return
[]
byte
{},
[]
byte
{}
,
err
return
privateKeyFixedLength
,
publicKeyFixedLength
,
err
}
pkh
:=
sha3
.
Sum256
(
indcpaPublicKey
)
rnd
:=
make
([]
byte
,
params
.
s
ym
b
ytes
)
rnd
:=
make
([]
byte
,
params
S
ym
B
ytes
)
_
,
err
=
rand
.
Read
(
rnd
)
if
err
!=
nil
{
return
[]
byte
{},
[]
byte
{}
,
err
return
privateKeyFixedLength
,
publicKeyFixedLength
,
err
}
privateKey
:=
append
(
indcpaPrivateKey
,
indcpaPublicKey
...
)
privateKey
=
append
(
privateKey
,
pkh
[
:
]
...
)
privateKey
=
append
(
privateKey
,
rnd
...
)
return
privateKey
,
indcpaPublicKey
,
nil
copy
(
privateKeyFixedLength
[
:
],
privateKey
)
copy
(
publicKeyFixedLength
[
:
],
indcpaPublicKey
)
return
privateKeyFixedLength
,
publicKeyFixedLength
,
nil
}
// KemEncrypt takes a public key (from KemKeypair) as input and returns a ciphertext and a 32-byte shared secret.
// An accompanying error is returned if no sufficient randomness could be obtained from the system.
func
KemEncrypt
(
publicKey
[]
byte
)
([]
byte
,
[]
byte
,
error
)
{
sharedSecret
:=
make
([]
byte
,
params
.
symbytes
)
buf
:=
make
([]
byte
,
2
*
params
.
symbytes
)
_
,
err
:=
rand
.
Read
(
buf
[
:
params
.
symbytes
])
func
KemEncrypt
(
publicKey
[
paramsPublicKeyBytes
]
byte
)
([
paramsIndcpaBytes
]
byte
,
[
paramsSymBytes
]
byte
,
error
)
{
var
ciphertextFixedLength
[
paramsIndcpaBytes
]
byte
var
sharedSecretFixedLength
[
paramsSymBytes
]
byte
sharedSecret
:=
make
([]
byte
,
paramsSymBytes
)
buf
:=
make
([]
byte
,
2
*
paramsSymBytes
)
_
,
err
:=
rand
.
Read
(
buf
[
:
paramsSymBytes
])
if
err
!=
nil
{
return
[]
byte
{},
[]
byte
{}
,
err
return
ciphertextFixedLength
,
sharedSecretFixedLength
,
err
}
buf1
:=
sha3
.
Sum256
(
buf
[
:
params
.
s
ym
b
ytes
])
buf2
:=
sha3
.
Sum256
(
publicKey
)
buf1
:=
sha3
.
Sum256
(
buf
[
:
params
S
ym
B
ytes
])
buf2
:=
sha3
.
Sum256
(
publicKey
[
:
]
)
kr
:=
sha3
.
Sum512
(
append
(
buf1
[
:
],
buf2
[
:
]
...
))
ciphertext
,
err
:=
indcpaEncrypt
(
buf1
[
:
],
publicKey
,
kr
[
params
.
s
ym
b
ytes
:
])
ciphertext
,
err
:=
indcpaEncrypt
(
buf1
[
:
],
publicKey
[
:
]
,
kr
[
params
S
ym
B
ytes
:
])
krc
:=
sha3
.
Sum256
(
ciphertext
)
sha3
.
ShakeSum256
(
sharedSecret
,
append
(
kr
[
:
params
.
symbytes
],
krc
[
:
]
...
))
return
ciphertext
,
sharedSecret
,
err
sha3
.
ShakeSum256
(
sharedSecret
,
append
(
kr
[
:
paramsSymBytes
],
krc
[
:
]
...
))
copy
(
ciphertextFixedLength
[
:
],
ciphertext
)
copy
(
sharedSecretFixedLength
[
:
],
sharedSecret
)
return
ciphertextFixedLength
,
sharedSecretFixedLength
,
err
}
// KemDecrypt takes a ciphertext (from KeyEncrypt), a private key (from KemKeypair) and returns a 32-byte shared secret.
// An accompanying error is returned if no sufficient randomness could be obtained from the system.
func
KemDecrypt
(
ciphertext
[]
byte
,
privateKey
[]
byte
)
([]
byte
,
error
)
{
sharedSecret
:=
make
([]
byte
,
params
.
symbytes
)
indcpaPrivateKey
:=
privateKey
[
:
params
.
indcpasecretkeybytes
]
pki
:=
params
.
indcpasecretkeybytes
+
params
.
indcpapublickeybytes
publicKey
:=
privateKey
[
params
.
indcpasecretkeybytes
:
pki
]
buf
:=
indcpaDecrypt
(
ciphertext
,
indcpaPrivateKey
)
ski
:=
params
.
secretkeybytes
-
2
*
params
.
symbytes
kr
:=
sha3
.
Sum512
(
append
(
buf
,
privateKey
[
ski
:
ski
+
params
.
symbytes
]
...
))
cmp
,
err
:=
indcpaEncrypt
(
buf
,
publicKey
,
kr
[
params
.
symbytes
:
])
fail
:=
byte
(
1
-
subtle
.
ConstantTimeCompare
(
ciphertext
,
cmp
))
krh
:=
sha3
.
Sum256
(
ciphertext
)
for
i
:=
0
;
i
<
params
.
symbytes
;
i
++
{
skx
:=
privateKey
[
:
params
.
secretkeybytes
-
params
.
symbytes
+
i
]
func
KemDecrypt
(
ciphertext
[
paramsIndcpaBytes
]
byte
,
privateKey
[
paramsSecretKeyBytes
]
byte
,
)
([
paramsSymBytes
]
byte
,
error
)
{
var
sharedSecretFixedLength
[
paramsSymBytes
]
byte
sharedSecret
:=
make
([]
byte
,
paramsSymBytes
)
indcpaPrivateKey
:=
privateKey
[
:
paramsIndcpaSecretKeyBytes
]
pki
:=
paramsIndcpaSecretKeyBytes
+
paramsIndcpaPublicKeyBytes
publicKey
:=
privateKey
[
paramsIndcpaSecretKeyBytes
:
pki
]
buf
:=
indcpaDecrypt
(
ciphertext
[
:
],
indcpaPrivateKey
)
ski
:=
paramsSecretKeyBytes
-
2
*
paramsSymBytes
kr
:=
sha3
.
Sum512
(
append
(
buf
,
privateKey
[
ski
:
ski
+
paramsSymBytes
]
...
))
cmp
,
err
:=
indcpaEncrypt
(
buf
,
publicKey
,
kr
[
paramsSymBytes
:
])
fail
:=
byte
(
1
-
subtle
.
ConstantTimeCompare
(
ciphertext
[
:
],
cmp
))
krh
:=
sha3
.
Sum256
(
ciphertext
[
:
])
for
i
:=
0
;
i
<
paramsSymBytes
;
i
++
{
skx
:=
privateKey
[
:
paramsSecretKeyBytes
-
paramsSymBytes
+
i
]
kr
[
i
]
=
kr
[
i
]
^
(
fail
&
(
kr
[
i
]
^
skx
[
i
]))
}
sha3
.
ShakeSum256
(
sharedSecret
,
append
(
kr
[
:
params
.
symbytes
],
krh
[
:
]
...
))
return
sharedSecret
,
err
sha3
.
ShakeSum256
(
sharedSecret
,
append
(
kr
[
:
paramsSymBytes
],
krh
[
:
]
...
))
copy
(
sharedSecretFixedLength
[
:
],
sharedSecret
)
return
sharedSecretFixedLength
,
err
}
main_test.go
View file @
bbe6792f
...
...
@@ -22,7 +22,7 @@ func TestMain(t *testing.T) {
if
err
!=
nil
{
t
.
Error
(
err
)
}
if
subtle
.
ConstantTimeCompare
(
ssA
,
ssB
)
==
0
{
if
subtle
.
ConstantTimeCompare
(
ssA
[
:
]
,
ssB
[
:
]
)
==
0
{
t
.
Error
(
"shared secret failed"
)
}
}
...
...
params.go
View file @
bbe6792f
...
...
@@ -3,38 +3,18 @@
package
kyberk2so
type
paramsStruct
struct
{
k
int
n
int
q
int
eta
int
polybytes
int
polycompressedbytes
int
polyvecbytes
int
polyveccompressedbytes
int
qinv
int
symbytes
int
secretkeybytes
int
publickeybytes
int
indcpasecretkeybytes
int
indcpapublickeybytes
int
indcpabytes
int
}
var
params
paramsStruct
=
paramsStruct
{
k
:
3
,
n
:
256
,
q
:
3329
,
eta
:
2
,
polybytes
:
384
,
polycompressedbytes
:
128
,
polyvecbytes
:
(
3
*
384
),
polyveccompressedbytes
:
(
3
*
320
),
qinv
:
62209
,
symbytes
:
32
,
secretkeybytes
:
((
3
*
384
)
+
((
3
*
384
)
+
32
)
+
2
*
32
),
publickeybytes
:
((
3
*
384
)
+
32
),
indcpasecretkeybytes
:
(
3
*
384
),
indcpapublickeybytes
:
((
3
*
384
)
+
32
),
indcpabytes
:
((
3
*
320
)
+
128
),
}
const
paramsK
int
=
3
const
paramsN
int
=
256
const
paramsQ
int
=
3329
const
paramsETA
int
=
2
const
paramsPolyBytes
int
=
384
const
paramsPolyCompressedBytes
int
=
128
const
paramsQinv
int
=
62209
const
paramsSymBytes
int
=
32
const
paramsPolyvecBytes
int
=
paramsK
*
paramsPolyBytes
const
paramsPolyvecCompressedBytes
int
=
paramsK
*
320
const
paramsSecretKeyBytes
int
=
paramsPolyvecBytes
+
((
paramsPolyvecBytes
+
paramsSymBytes
)
+
2
*
paramsSymBytes
)
const
paramsPublicKeyBytes
int
=
paramsPolyvecBytes
+
paramsSymBytes
const
paramsIndcpaSecretKeyBytes
int
=
paramsK
*
paramsPolyBytes
const
paramsIndcpaPublicKeyBytes
int
=
paramsPolyvecBytes
+
paramsSymBytes
const
paramsIndcpaBytes
int
=
paramsPolyvecCompressedBytes
+
paramsPolyCompressedBytes
poly.go
View file @
bbe6792f
...
...
@@ -13,27 +13,27 @@ type polyvec struct {
func
polyNew
()
poly
{
var
p
poly
p
.
coeffs
=
make
([]
int16
,
params
.
n
)
p
.
coeffs
=
make
([]
int16
,
params
N
)
return
p
}
func
polyvecNew
()
polyvec
{
var
pv
polyvec
pv
.
vec
=
make
([]
poly
,
params
.
k
)
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
pv
.
vec
=
make
([]
poly
,
params
K
)
for
i
:=
0
;
i
<
params
K
;
i
++
{
pv
.
vec
[
i
]
=
polyNew
()
}
return
pv
}
func
polyCompress
(
a
poly
)
[]
byte
{
r
:=
make
([]
byte
,
params
.
p
oly
c
ompressed
b
ytes
)
r
:=
make
([]
byte
,
params
P
oly
C
ompressed
B
ytes
)
t
:=
make
([]
byte
,
8
)
a
=
polyCSubQ
(
a
)
rr
:=
0
for
i
:=
0
;
i
<
params
.
n
/
8
;
i
++
{
for
i
:=
0
;
i
<
params
N
/
8
;
i
++
{
for
j
:=
0
;
j
<
8
;
j
++
{
t
[
j
]
=
byte
((((
uint16
(
a
.
coeffs
[
8
*
i
+
j
])
<<
4
)
+
uint16
(
params
.
q
/
2
))
/
uint16
(
params
.
q
))
&
15
)
t
[
j
]
=
byte
((((
uint16
(
a
.
coeffs
[
8
*
i
+
j
])
<<
4
)
+
uint16
(
params
Q
/
2
))
/
uint16
(
params
Q
))
&
15
)
}
r
[
rr
+
0
]
=
t
[
0
]
|
(
t
[
1
]
<<
4
)
r
[
rr
+
1
]
=
t
[
2
]
|
(
t
[
3
]
<<
4
)
...
...
@@ -47,9 +47,9 @@ func polyCompress(a poly) []byte {
func
polyDecompress
(
a
[]
byte
)
poly
{
r
:=
polyNew
()
aa
:=
0
for
i
:=
0
;
i
<
params
.
n
/
2
;
i
++
{
r
.
coeffs
[
2
*
i
+
0
]
=
int16
(((
uint16
(
a
[
aa
]
&
15
)
*
uint16
(
params
.
q
))
+
8
)
>>
4
)
r
.
coeffs
[
2
*
i
+
1
]
=
int16
(((
uint16
(
a
[
aa
]
>>
4
)
*
uint16
(
params
.
q
))
+
8
)
>>
4
)
for
i
:=
0
;
i
<
params
N
/
2
;
i
++
{
r
.
coeffs
[
2
*
i
+
0
]
=
int16
(((
uint16
(
a
[
aa
]
&
15
)
*
uint16
(
params
Q
))
+
8
)
>>
4
)
r
.
coeffs
[
2
*
i
+
1
]
=
int16
(((
uint16
(
a
[
aa
]
>>
4
)
*
uint16
(
params
Q
))
+
8
)
>>
4
)
aa
=
aa
+
1
}
return
r
...
...
@@ -57,9 +57,9 @@ func polyDecompress(a []byte) poly {
func
polyToBytes
(
a
poly
)
[]
byte
{
var
t0
,
t1
uint16
r
:=
make
([]
byte
,
params
.
p
oly
b
ytes
)
r
:=
make
([]
byte
,
params
P
oly
B
ytes
)
a
=
polyCSubQ
(
a
)
for
i
:=
0
;
i
<
params
.
n
/
2
;
i
++
{
for
i
:=
0
;
i
<
params
N
/
2
;
i
++
{
t0
=
uint16
(
a
.
coeffs
[
2
*
i
])
t1
=
uint16
(
a
.
coeffs
[
2
*
i
+
1
])
r
[
3
*
i
+
0
]
=
byte
(
t0
>>
0
)
...
...
@@ -71,7 +71,7 @@ func polyToBytes(a poly) []byte {
func
polyFromBytes
(
a
[]
byte
)
poly
{
r
:=
polyNew
()
for
i
:=
0
;
i
<
params
.
n
/
2
;
i
++
{
for
i
:=
0
;
i
<
params
N
/
2
;
i
++
{
r
.
coeffs
[
2
*
i
]
=
int16
(((
uint16
(
a
[
3
*
i
+
0
])
>>
0
)
|
(
uint16
(
a
[
3
*
i
+
1
])
<<
8
))
&
0xFFF
)
r
.
coeffs
[
2
*
i
+
1
]
=
int16
(((
uint16
(
a
[
3
*
i
+
1
])
>>
4
)
|
(
uint16
(
a
[
3
*
i
+
2
])
<<
4
))
&
0xFFF
)
}
...
...
@@ -81,23 +81,23 @@ func polyFromBytes(a []byte) poly {
func
polyFromMsg
(
msg
[]
byte
)
poly
{
r
:=
polyNew
()
var
mask
int16
for
i
:=
0
;
i
<
params
.
n
/
8
;
i
++
{
for
i
:=
0
;
i
<
params
N
/
8
;
i
++
{
for
j
:=
0
;
j
<
8
;
j
++
{
mask
=
-
int16
((
msg
[
i
]
>>
j
)
&
1
)
r
.
coeffs
[
8
*
i
+
j
]
=
mask
&
int16
((
params
.
q
+
1
)
/
2
)
r
.
coeffs
[
8
*
i
+
j
]
=
mask
&
int16
((
params
Q
+
1
)
/
2
)
}
}
return
r
}
func
polyToMsg
(
a
poly
)
[]
byte
{
msg
:=
make
([]
byte
,
params
.
s
ym
b
ytes
)
msg
:=
make
([]
byte
,
params
S
ym
B
ytes
)
var
t
uint16
a
=
polyCSubQ
(
a
)
for
i
:=
0
;
i
<
params
.
n
/
8
;
i
++
{
for
i
:=
0
;
i
<
params
N
/
8
;
i
++
{
msg
[
i
]
=
0
for
j
:=
0
;
j
<
8
;
j
++
{
t
=
(((
uint16
(
a
.
coeffs
[
8
*
i
+
j
])
<<
1
)
+
uint16
(
params
.
q
/
2
))
/
uint16
(
params
.
q
))
&
1
t
=
(((
uint16
(
a
.
coeffs
[
8
*
i
+
j
])
<<
1
)
+
uint16
(
params
Q
/
2
))
/
uint16
(
params
Q
))
&
1
msg
[
i
]
|=
byte
(
t
<<
j
)
}
}
...
...
@@ -105,7 +105,7 @@ func polyToMsg(a poly) []byte {
}
func
polyGetNoise
(
seed
[]
byte
,
nonce
byte
)
poly
{
l
:=
params
.
eta
*
params
.
n
/
4
l
:=
params
ETA
*
params
N
/
4
p
:=
indcpaPrf
(
l
,
seed
,
nonce
)
return
byteopsCbd
(
p
)
}
...
...
@@ -124,7 +124,7 @@ func polyInvNttToMont(a poly) poly {
func
polyBaseMulMontgomery
(
a
poly
,
b
poly
)
poly
{
r
:=
polyNew
()
for
i
:=
0
;
i
<
params
.
n
/
4
;
i
++
{
for
i
:=
0
;
i
<
params
N
/
4
;
i
++
{
rx
:=
nttBaseMul
(
a
.
coeffs
[
4
*
i
+
0
],
a
.
coeffs
[
4
*
i
+
1
],
b
.
coeffs
[
4
*
i
+
0
],
b
.
coeffs
[
4
*
i
+
1
],
...
...
@@ -145,8 +145,8 @@ func polyBaseMulMontgomery(a poly, b poly) poly {
func
polyToMont
(
a
poly
)
poly
{
r
:=
polyNew
()
var
f
int16
=
int16
((
uint64
(
1
)
<<
32
)
%
uint64
(
params
.
q
))
for
i
:=
0
;
i
<
params
.
n
;
i
++
{
var
f
int16
=
int16
((
uint64
(
1
)
<<
32
)
%
uint64
(
params
Q
))
for
i
:=
0
;
i
<
params
N
;
i
++
{
r
.
coeffs
[
i
]
=
byteopsMontgomeryReduce
(
int32
(
a
.
coeffs
[
i
])
*
int32
(
f
))
}
return
r
...
...
@@ -154,7 +154,7 @@ func polyToMont(a poly) poly {
func
polyReduce
(
a
poly
)
poly
{
r
:=
polyNew
()
for
i
:=
0
;
i
<
params
.
n
;
i
++
{
for
i
:=
0
;
i
<
params
N
;
i
++
{
r
.
coeffs
[
i
]
=
byteopsBarrettReduce
(
a
.
coeffs
[
i
])
}
return
r
...
...
@@ -162,7 +162,7 @@ func polyReduce(a poly) poly {
func
polyCSubQ
(
a
poly
)
poly
{
r
:=
polyNew
()
for
i
:=
0
;
i
<
params
.
n
;
i
++
{
for
i
:=
0
;
i
<
params
N
;
i
++
{
r
.
coeffs
[
i
]
=
byteopsCSubQ
(
a
.
coeffs
[
i
])
}
return
r
...
...
@@ -170,7 +170,7 @@ func polyCSubQ(a poly) poly {
func
polyAdd
(
a
poly
,
b
poly
)
poly
{
r
:=
polyNew
()
for
i
:=
0
;
i
<
params
.
n
;
i
++
{
for
i
:=
0
;
i
<
params
N
;
i
++
{
r
.
coeffs
[
i
]
=
a
.
coeffs
[
i
]
+
b
.
coeffs
[
i
]
}
return
r
...
...
@@ -178,21 +178,21 @@ func polyAdd(a poly, b poly) poly {
func
polySub
(
a
poly
,
b
poly
)
poly
{
r
:=
polyNew
()
for
i
:=
0
;
i
<
params
.
n
;
i
++
{
for
i
:=
0
;
i
<
params
N
;
i
++
{
r
.
coeffs
[
i
]
=
a
.
coeffs
[
i
]
-
b
.
coeffs
[
i
]
}
return
r
}
func
polyvecCompress
(
a
polyvec
)
[]
byte
{
r
:=
make
([]
byte
,
params
.
p
olyvec
c
ompressed
b
ytes
)
r
:=
make
([]
byte
,
params
P
olyvec
C
ompressed
B
ytes
)
t
:=
make
([]
uint16
,
4
)
a
=
polyvecCSubQ
(
a
)
rr
:=
0
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
j
:=
0
;
j
<
params
.
n
/
4
;
j
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
for
j
:=
0
;
j
<
params
N
/
4
;
j
++
{
for
k
:=
0
;
k
<
4
;
k
++
{
t
[
k
]
=
uint16
((((
uint32
(
a
.
vec
[
i
]
.
coeffs
[
4
*
j
+
k
])
<<
10
)
+
uint32
(
params
.
q
/
2
))
/
uint32
(
params
.
q
))
&
0x3ff
)
t
[
k
]
=
uint16
((((
uint32
(
a
.
vec
[
i
]
.
coeffs
[
4
*
j
+
k
])
<<
10
)
+
uint32
(
params
Q
/
2
))
/
uint32
(
params
Q
))
&
0x3ff
)
}
r
[
rr
+
0
]
=
byte
(
t
[
0
]
>>
0
)
r
[
rr
+
1
]
=
byte
((
t
[
0
]
>>
8
)
|
(
t
[
1
]
<<
2
))
...
...
@@ -209,15 +209,15 @@ func polyvecDecompress(a []byte) polyvec {
r
:=
polyvecNew
()
aa
:=
0
t
:=
make
([]
uint16
,
4
)
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
j
:=
0
;
j
<
params
.
n
/
4
;
j
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
for
j
:=
0
;
j
<
params
N
/
4
;
j
++
{
t
[
0
]
=
(
uint16
(
a
[
aa
+
0
])
>>
0
)
|
(
uint16
(
a
[
aa
+
1
])
<<
8
)
t
[
1
]
=
(
uint16
(
a
[
aa
+
1
])
>>
2
)
|
(
uint16
(
a
[
aa
+
2
])
<<
6
)
t
[
2
]
=
(
uint16
(
a
[
aa
+
2
])
>>
4
)
|
(
uint16
(
a
[
aa
+
3
])
<<
4
)
t
[
3
]
=
(
uint16
(
a
[
aa
+
3
])
>>
6
)
|
(
uint16
(
a
[
aa
+
4
])
<<
2
)
aa
=
aa
+
5
for
k
:=
0
;
k
<
4
;
k
++
{
r
.
vec
[
i
]
.
coeffs
[
4
*
j
+
k
]
=
int16
((
uint32
(
t
[
k
]
&
0x3FF
)
*
uint32
(
params
.
q
)
+
512
)
>>
10
)
r
.
vec
[
i
]
.
coeffs
[
4
*
j
+
k
]
=
int16
((
uint32
(
t
[
k
]
&
0x3FF
)
*
uint32
(
params
Q
)
+
512
)
>>
10
)
}
}
}
...
...
@@ -226,7 +226,7 @@ func polyvecDecompress(a []byte) polyvec {
func
polyvecToBytes
(
a
polyvec
)
[]
byte
{
r
:=
[]
byte
{}
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
r
=
append
(
r
,
polyToBytes
(
a
.
vec
[
i
])
...
)
}
return
r
...
...
@@ -234,9 +234,9 @@ func polyvecToBytes(a polyvec) []byte {
func
polyvecFromBytes
(
a
[]
byte
)
polyvec
{
r
:=
polyvecNew
()
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
start
:=
(
i
*
params
.
p
oly
b
ytes
)
end
:=
(
i
+
1
)
*
params
.
p
oly
b
ytes
for
i
:=
0
;
i
<
params
K
;
i
++
{
start
:=
(
i
*
params
P
oly
B
ytes
)
end
:=
(
i
+
1
)
*
params
P
oly
B
ytes
r
.
vec
[
i
]
=
polyFromBytes
(
a
[
start
:
end
])
}
return
r
...
...
@@ -244,7 +244,7 @@ func polyvecFromBytes(a []byte) polyvec {
func
polyvecNtt
(
a
polyvec
)
polyvec
{
r
:=
polyvecNew
()
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{
r
.
vec
[
i
]
=
polyNtt
(
a
.
vec
[
i
])
}
return
r
...
...
@@ -252,7 +252,7 @@ func polyvecNtt(a polyvec) polyvec {
func
polyvecInvNttToMont
(
a
polyvec
)
polyvec
{
r
:=
polyvecNew
()
for
i
:=
0
;
i
<
params
.
k
;
i
++
{
for
i
:=
0
;
i
<
params
K
;
i
++
{