1
0
mirror of https://github.com/henrydcase/nobs.git synced 2024-11-25 16:41:32 +00:00
nobs/dh/csidh/utils_test.go

135 lines
2.5 KiB
Go

package csidh
import (
"fmt"
"math/big"
mrand "math/rand"
)
var (
// Number of interations
numIter = 10
// Modulus
modulus, _ = new(big.Int).SetString(fp2S(p), 16)
// Zero in fp
zeroFp512 = fp{}
// One in fp
oneFp512 = fp{1, 0, 0, 0, 0, 0, 0, 0}
// file with KAT vectors
katFile = "testdata/csidh_testvectors.dat"
)
// Converts dst to Montgomery if "toMont==true" or from Montgomery domain otherwise.
func toMont(dst *big.Int, toMont bool) {
var bigP, bigR big.Int
intSetU64(&bigP, p[:])
bigR.SetUint64(1)
bigR.Lsh(&bigR, 512)
if !toMont {
bigR.ModInverse(&bigR, &bigP)
}
dst.Mul(dst, &bigR)
dst.Mod(dst, &bigP)
}
func fp2S(v fp) string {
var str string
for i := 0; i < 8; i++ {
str = fmt.Sprintf("%016x", v[i]) + str
}
return str
}
// zeroize fp.
func zero(v *fp) {
for i := range *v {
v[i] = 0
}
}
// returns random value in a range (0,p).
func randomFp() fp {
var u fp
for i := 0; i < 8; i++ {
u[i] = mrand.Uint64()
}
return u
}
// return x==y for fp.
func eqFp(l, r *fp) bool {
for idx := range l {
if l[idx] != r[idx] {
return false
}
}
return true
}
// return x==y for point.
func ceqpoint(l, r *point) bool {
return eqFp(&l.x, &r.x) && eqFp(&l.z, &r.z)
}
// Converts src to big.Int. Function assumes that src is a slice of uint64
// values encoded in little-endian byte order.
func intSetU64(dst *big.Int, src []uint64) {
var tmp big.Int
dst.SetUint64(0)
for i := range src {
tmp.SetUint64(src[i])
tmp.Lsh(&tmp, uint(i*64))
dst.Add(dst, &tmp)
}
}
// Converts src to an array of uint64 values encoded in little-endian
// byte order.
func intGetU64(src *big.Int) []uint64 {
var tmp, mod big.Int
dst := make([]uint64, (src.BitLen()/64)+1)
u64 := uint64(0)
u64--
mod.SetUint64(u64)
for i := 0; i < (src.BitLen()/64)+1; i++ {
tmp.Set(src)
tmp.Rsh(&tmp, uint(i)*64)
tmp.And(&tmp, &mod)
dst[i] = tmp.Uint64()
}
return dst
}
// Returns projective coordinate X of normalized EC 'point' (point.x / point.z).
func toNormX(point *point) big.Int {
var bigP, bigDnt, bigDor big.Int
intSetU64(&bigP, p[:])
intSetU64(&bigDnt, point.x[:])
intSetU64(&bigDor, point.z[:])
bigDor.ModInverse(&bigDor, &bigP)
bigDnt.Mul(&bigDnt, &bigDor)
bigDnt.Mod(&bigDnt, &bigP)
return bigDnt
}
// Converts string to fp element in Montgomery domain of cSIDH-512.
func toFp(num string) fp {
var tmp big.Int
var ok bool
var ret fp
_, ok = tmp.SetString(num, 0)
if !ok {
panic("Can't parse a number")
}
toMont(&tmp, true)
copy(ret[:], intGetU64(&tmp))
return ret
}