mirror of
https://github.com/luxfi/crystals-go.git
synced 2026-10-30 16:59:05 +00:00
315 lines
5.6 KiB
Go
315 lines
5.6 KiB
Go
package dilithium
|
|
|
|
import (
|
|
cRand "crypto/rand"
|
|
"io"
|
|
"math/rand"
|
|
"testing"
|
|
)
|
|
|
|
/** Test Poly **/
|
|
|
|
func TestPoly(t *testing.T) {
|
|
var seed [32]byte
|
|
rand := cRand.Reader
|
|
io.ReadFull(rand, seed[:])
|
|
|
|
p := polyUniform(seed, 0)
|
|
p2 := polyUniform(seed, 1)
|
|
|
|
a := add(p, p2)
|
|
|
|
for i := uint(0); i < n; i++ {
|
|
if a[i] != (p[i] + p2[i]) {
|
|
t.Fatalf("Add failed")
|
|
}
|
|
}
|
|
|
|
b := sub(p, p2)
|
|
for i := uint(0); i < n; i++ {
|
|
if b[i] != (p[i] - p2[i]) {
|
|
t.Fatalf("Sub failed")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFreeze(t *testing.T) {
|
|
|
|
a := int32(q + 1)
|
|
if freeze(a) != 1 {
|
|
t.Fatal("Freeze did not work")
|
|
}
|
|
|
|
var seed [32]byte
|
|
rand := cRand.Reader
|
|
io.ReadFull(rand, seed[:])
|
|
|
|
var p, b Poly
|
|
p = polyUniform(seed, 0)
|
|
b = add(p, p)
|
|
//some coefs must be > Q
|
|
c := b
|
|
c.freeze()
|
|
for i := uint(0); i < n; i++ {
|
|
if c[i] != (b[i] % q) {
|
|
t.Fatalf("Freeze failed")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRandPoly(t *testing.T) {
|
|
var seed [32]byte
|
|
copy(seed[:], []byte("very random seed that I will use"))
|
|
var p, p2 Poly
|
|
p = polyUniform(seed, 0)
|
|
p2 = polyUniform(seed, 0)
|
|
for i := uint(0); i < n; i++ {
|
|
if p[i] != p2[i] {
|
|
t.Fatalf("Seed did not work")
|
|
}
|
|
}
|
|
p2 = polyUniform(seed, 1)
|
|
counter := 0
|
|
for i := uint(0); i < n; i++ {
|
|
if p[i] == p2[i] {
|
|
counter++
|
|
}
|
|
if counter == n {
|
|
t.Fatalf("Seed did not work")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSamples(t *testing.T) {
|
|
var seed [64]byte
|
|
rand := cRand.Reader
|
|
io.ReadFull(rand, seed[:])
|
|
|
|
ETA := int32(2)
|
|
|
|
var p, p2 Poly
|
|
p = polyUniformEta(seed, 1, ETA)
|
|
if !p.isBelow(ETA + 1) { //i > eta
|
|
t.Fatalf("PolyUniformEta sampled failed %v\n", p)
|
|
}
|
|
var rhoP [64]byte
|
|
io.ReadFull(rand, rhoP[:])
|
|
GAMMA1 := int32(1 << 17)
|
|
p2 = polyUniformGamma1(rhoP, 0, GAMMA1)
|
|
if !p2.isBelow(GAMMA1 + 1) { //if stritcly above
|
|
t.Fatalf("PolyUnifromGamma1 sampled failed %v\n", p2)
|
|
}
|
|
}
|
|
|
|
func TestExpand(t *testing.T) {
|
|
var seed [32]byte
|
|
copy(seed[:], []byte("very random seed that I will use"))
|
|
K, L := 6, 5
|
|
A := expandSeed(seed, K, L)
|
|
Abis := expandSeed(seed, K, L)
|
|
for i := 0; i < K; i++ {
|
|
for j := 0; j < L; j++ {
|
|
if A[i][j] != Abis[i][j] {
|
|
t.Fatalf("Seed did not work")
|
|
}
|
|
}
|
|
}
|
|
for j := 1; j < L; j++ {
|
|
if A[0][0] == A[0][j] {
|
|
t.Fatalf("Poly is repeating %v against %d: %v\n", A[0][0], j, A[0][j])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMult(t *testing.T) {
|
|
var p, p2 Poly
|
|
|
|
p[0] = 1
|
|
p2[0] = 1
|
|
p.ntt()
|
|
p2.ntt()
|
|
res := montMul(p, p2)
|
|
p.invntt()
|
|
p2.invntt()
|
|
res.invntt()
|
|
res.freeze()
|
|
if res[0] != 1 {
|
|
t.Fatalf("Mult did not work %v\n", res)
|
|
}
|
|
for i := 1; i < n; i++ {
|
|
if res[i] != 0 {
|
|
t.Fatal("Mult did not work")
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Test Utils **/
|
|
|
|
func TestPow2Round(t *testing.T) {
|
|
r := int32(rand.Intn(q - 1))
|
|
r1, r0 := power2Round(r)
|
|
if (-(1 << (d - 1)) >= r0) || (r0 >= 1<<(d-1)) {
|
|
t.Fatalf("Power2Round failed r0 not in the bounds")
|
|
}
|
|
if int32(r1)*(1<<d)+r0 != int32(r) {
|
|
t.Fatal("Power2Round failed")
|
|
}
|
|
}
|
|
|
|
func TestDecompose(t *testing.T) {
|
|
g2 := int32(q-1) / 88
|
|
r := int32(rand.Intn(int(g2 + 1)))
|
|
r1, r0 := decompose(r, g2)
|
|
|
|
if r1*g2+r0 != r {
|
|
println(r)
|
|
println(r1*g2 + freeze(r0))
|
|
println(r0)
|
|
t.Fatal("Decompose failed")
|
|
}
|
|
}
|
|
|
|
/** Test Hints **/
|
|
|
|
func TestMakeHints(t *testing.T) {
|
|
d := NewDilithium3(false)
|
|
r := int32(rand.Intn(q))
|
|
g2 := int32(d.params.GAMMA2)
|
|
r1, r0 := decompose(r, g2)
|
|
//useHint( r - f, makeHint( r0 - f, r1 ) ) = r1.
|
|
if makeHint(r1, r0, g2) != 0 {
|
|
t.Fatal("Make hint failed")
|
|
}
|
|
r0 = int32(1 + d.params.GAMMA2)
|
|
if makeHint(r1, r0, g2) != 1 {
|
|
t.Fatal("Make hint failed")
|
|
}
|
|
}
|
|
|
|
func TestUseHints(t *testing.T) {
|
|
d := NewDilithium3(false)
|
|
r := int32(rand.Intn(q))
|
|
g2 := d.params.GAMMA2
|
|
r1, r0PQ := decompose(r, g2)
|
|
r0 := r0PQ
|
|
//useHint( r - f, makeHint( r0 - f, r1 ) ) = r1.
|
|
if useHint(r, makeHint(r1, r0, g2), g2) != r1 {
|
|
t.Fatal("Use hint failed")
|
|
}
|
|
if useHint(r, makeHint(r1, r0+n, g2), g2) != r1 {
|
|
t.Fatal("Use hint failed")
|
|
}
|
|
z := int32(d.params.GAMMA2 + 1)
|
|
if useHint(r, makeHint(r1, z, g2), g2) == r1 {
|
|
t.Fatal("Use hint failed")
|
|
}
|
|
}
|
|
|
|
//test wether we can pack (NTT(s)) the same way as s: answer is no...
|
|
/**
|
|
func OneTimeRunTestPackSNTT(t *testing.T) {
|
|
var seed [64]byte
|
|
seed[0] = 1
|
|
L := 6
|
|
ETA := int32(2)
|
|
SIZES := 640
|
|
s1 := make(Vec, L)
|
|
for i := 0; i < L; i++ {
|
|
s1[i] = polyUniformEta(seed, uint16(i), 4)
|
|
}
|
|
s1.ntt(L)
|
|
ps1 := packS(s1, L, SIZES, ETA)
|
|
s1Rec := unpackS(ps1, L, SIZES, ETA)
|
|
if !s1[0].equal(s1Rec[0]) {
|
|
t.Fatal("could not reconstruct after NTT")
|
|
}
|
|
}**/
|
|
|
|
func TestNTT1(t *testing.T) {
|
|
var seed [SEEDBYTES]byte
|
|
for i := 0; i < 100; i++ {
|
|
cRand.Read(seed[:])
|
|
p := polyUniform(seed, uint16(0))
|
|
expected := p
|
|
expected.addQ()
|
|
|
|
p.ntt()
|
|
p.invntt()
|
|
p.addQ()
|
|
p.fromMont()
|
|
p.addQ()
|
|
|
|
for i := uint(0); i < n; i++ {
|
|
if p[i] != expected[i] {
|
|
t.Fatalf("Failed")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNTT0(t *testing.T) {
|
|
var seed [SEEDBYTES]byte
|
|
for i := 0; i < 100; i++ {
|
|
cRand.Read(seed[:])
|
|
p := polyUniform(seed, uint16(0))
|
|
|
|
expected := p
|
|
|
|
p.ntt()
|
|
p.tomont()
|
|
p.invntt()
|
|
p.addQ()
|
|
|
|
for i := uint(0); i < n; i++ {
|
|
if p[i] != expected[i] {
|
|
t.Fatalf("Failed")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNTTAdd(t *testing.T) {
|
|
var seed [SEEDBYTES]byte
|
|
cRand.Read(seed[:])
|
|
p := polyUniform(seed, uint16(0))
|
|
p2 := polyUniform(seed, uint16(1))
|
|
|
|
expected := add(p, p2)
|
|
expected.freeze()
|
|
|
|
p.ntt()
|
|
p2.ntt()
|
|
res := add(p, p2)
|
|
res.invntt()
|
|
res.addQ()
|
|
res.fromMont()
|
|
|
|
if !res.equal(expected) {
|
|
t.Fatal("Failed")
|
|
}
|
|
}
|
|
|
|
func TestNTTAdd0(t *testing.T) {
|
|
var seed [SEEDBYTES]byte
|
|
cRand.Read(seed[:])
|
|
p := polyUniform(seed, uint16(0))
|
|
p2 := polyUniform(seed, uint16(1))
|
|
p3 := add(p, p2)
|
|
p3.freeze()
|
|
|
|
expected := add(p, p3)
|
|
expected.freeze()
|
|
|
|
p.ntt()
|
|
p3.ntt()
|
|
p.tomont()
|
|
p3.tomont()
|
|
res := add(p, p3)
|
|
res.invntt()
|
|
res.addQ()
|
|
|
|
if !res.equal(expected) {
|
|
t.Fatal("Failed")
|
|
}
|
|
}
|