1
0
mirror of https://github.com/henrydcase/nobs.git synced 2024-11-26 09:01:20 +00:00

export more symbols from common

This commit is contained in:
Henry Case 2020-05-16 22:37:41 +00:00
parent a152c09fd5
commit 2500d74484
3 changed files with 55 additions and 57 deletions

View File

@ -97,11 +97,9 @@ func TestEphemeralKeyExchange(t *testing.T) {
checkErr(t, GeneratePrivateKey(&prv2, rng), "PrivateKey generation failed") checkErr(t, GeneratePrivateKey(&prv2, rng), "PrivateKey generation failed")
GeneratePublicKey(&pub2, &prv2, rng) GeneratePublicKey(&pub2, &prv2, rng)
Ok(t, Ok(t, DeriveSecret(&ss1, &pub1, &prv2, rng),
DeriveSecret(&ss1, &pub1, &prv2, rng),
"Derivation failed") "Derivation failed")
Ok(t, Ok(t, DeriveSecret(&ss2, &pub2, &prv1, rng),
DeriveSecret(&ss2, &pub2, &prv1, rng),
"Derivation failed") "Derivation failed")
if !bytes.Equal(ss1[:], ss2[:]) { if !bytes.Equal(ss1[:], ss2[:]) {

View File

@ -15,23 +15,23 @@ type KeyVariant uint
// Base type for public and private key. Used mainly to carry domain // Base type for public and private key. Used mainly to carry domain
// parameters. // parameters.
type key struct { type Key struct {
// Domain parameters of the algorithm to be used with a key // Domain parameters of the algorithm to be used with a key
params *common.SidhParams Params *common.SidhParams
// Flag indicates wether corresponds to 2-, 3-torsion group or SIKE // Flag indicates wether corresponds to 2-, 3-torsion group or SIKE
keyVariant KeyVariant KeyVariant KeyVariant
} }
// Defines operations on public key // Defines operations on public key
type PublicKey struct { type PublicKey struct {
key Key
// x-coordinates of P,Q,P-Q in this exact order // x-coordinates of P,Q,P-Q in this exact order
affine3Pt [3]common.Fp2 affine3Pt [3]common.Fp2
} }
// Defines operations on private key // Defines operations on private key
type PrivateKey struct { type PrivateKey struct {
key Key
// Secret key // Secret key
Scalar []byte Scalar []byte
// Used only by KEM // Used only by KEM
@ -59,14 +59,14 @@ const (
) )
// Accessor to key variant. // Accessor to key variant.
func (key *key) Variant() KeyVariant { func (key *Key) Variant() KeyVariant {
return key.keyVariant return key.KeyVariant
} }
// NewPublicKey initializes public key. // NewPublicKey initializes public key.
// Usage of this function guarantees that the object is correctly initialized. // Usage of this function guarantees that the object is correctly initialized.
func NewPublicKey(id uint8, v KeyVariant) *PublicKey { func NewPublicKey(id uint8, v KeyVariant) *PublicKey {
return &PublicKey{key: key{params: common.Params(id), keyVariant: v}} return &PublicKey{Key: Key{Params: common.Params(id), KeyVariant: v}}
} }
// Import clears content of the public key currently stored in the structure // Import clears content of the public key currently stored in the structure
@ -76,11 +76,11 @@ func (pub *PublicKey) Import(input []byte) error {
if len(input) != pub.Size() { if len(input) != pub.Size() {
return errors.New("sidh: input to short") return errors.New("sidh: input to short")
} }
ssSz := pub.params.SharedSecretSize ssSz := pub.Params.SharedSecretSize
common.BytesToFp2(&pub.affine3Pt[0], input[0:ssSz], pub.params.Bytelen) common.BytesToFp2(&pub.affine3Pt[0], input[0:ssSz], pub.Params.Bytelen)
common.BytesToFp2(&pub.affine3Pt[1], input[ssSz:2*ssSz], pub.params.Bytelen) common.BytesToFp2(&pub.affine3Pt[1], input[ssSz:2*ssSz], pub.Params.Bytelen)
common.BytesToFp2(&pub.affine3Pt[2], input[2*ssSz:3*ssSz], pub.params.Bytelen) common.BytesToFp2(&pub.affine3Pt[2], input[2*ssSz:3*ssSz], pub.Params.Bytelen)
switch pub.params.ID { switch pub.Params.ID {
case Fp434: case Fp434:
p434.ToMontgomery(&pub.affine3Pt[0], &pub.affine3Pt[0]) p434.ToMontgomery(&pub.affine3Pt[0], &pub.affine3Pt[0])
p434.ToMontgomery(&pub.affine3Pt[1], &pub.affine3Pt[1]) p434.ToMontgomery(&pub.affine3Pt[1], &pub.affine3Pt[1])
@ -103,8 +103,8 @@ func (pub *PublicKey) Import(input []byte) error {
// returned byte string is filled with zeros. // returned byte string is filled with zeros.
func (pub *PublicKey) Export(out []byte) { func (pub *PublicKey) Export(out []byte) {
var feTmp [3]common.Fp2 var feTmp [3]common.Fp2
ssSz := pub.params.SharedSecretSize ssSz := pub.Params.SharedSecretSize
switch pub.params.ID { switch pub.Params.ID {
case Fp434: case Fp434:
p434.FromMontgomery(&feTmp[0], &pub.affine3Pt[0]) p434.FromMontgomery(&feTmp[0], &pub.affine3Pt[0])
p434.FromMontgomery(&feTmp[1], &pub.affine3Pt[1]) p434.FromMontgomery(&feTmp[1], &pub.affine3Pt[1])
@ -120,27 +120,27 @@ func (pub *PublicKey) Export(out []byte) {
default: default:
panic("Unsupported key") panic("Unsupported key")
} }
common.Fp2ToBytes(out[0:ssSz], &feTmp[0], pub.params.Bytelen) common.Fp2ToBytes(out[0:ssSz], &feTmp[0], pub.Params.Bytelen)
common.Fp2ToBytes(out[ssSz:2*ssSz], &feTmp[1], pub.params.Bytelen) common.Fp2ToBytes(out[ssSz:2*ssSz], &feTmp[1], pub.Params.Bytelen)
common.Fp2ToBytes(out[2*ssSz:3*ssSz], &feTmp[2], pub.params.Bytelen) common.Fp2ToBytes(out[2*ssSz:3*ssSz], &feTmp[2], pub.Params.Bytelen)
} }
// Size returns size of the public key in bytes. // Size returns size of the public key in bytes.
func (pub *PublicKey) Size() int { func (pub *PublicKey) Size() int {
return pub.params.PublicKeySize return pub.Params.PublicKeySize
} }
// NewPrivateKey initializes private key. // NewPrivateKey initializes private key.
// Usage of this function guarantees that the object is correctly initialized. // Usage of this function guarantees that the object is correctly initialized.
func NewPrivateKey(id uint8, v KeyVariant) *PrivateKey { func NewPrivateKey(id uint8, v KeyVariant) *PrivateKey {
prv := &PrivateKey{key: key{params: common.Params(id), keyVariant: v}} prv := &PrivateKey{Key: Key{Params: common.Params(id), KeyVariant: v}}
if (v & KeyVariantSidhA) == KeyVariantSidhA { if (v & KeyVariantSidhA) == KeyVariantSidhA {
prv.Scalar = make([]byte, prv.params.A.SecretByteLen) prv.Scalar = make([]byte, prv.Params.A.SecretByteLen)
} else { } else {
prv.Scalar = make([]byte, prv.params.B.SecretByteLen) prv.Scalar = make([]byte, prv.Params.B.SecretByteLen)
} }
if v == KeyVariantSike { if v == KeyVariantSike {
prv.S = make([]byte, prv.params.MsgLen) prv.S = make([]byte, prv.Params.MsgLen)
} }
return prv return prv
} }
@ -156,14 +156,14 @@ func (prv *PrivateKey) Export(out []byte) {
func (prv *PrivateKey) Size() int { func (prv *PrivateKey) Size() int {
tmp := len(prv.Scalar) tmp := len(prv.Scalar)
if prv.Variant() == KeyVariantSike { if prv.Variant() == KeyVariantSike {
tmp += prv.params.MsgLen tmp += prv.Params.MsgLen
} }
return tmp return tmp
} }
// Size returns size of the shared secret. // Size returns size of the shared secret.
func (prv *PrivateKey) SharedSecretSize() int { func (prv *PrivateKey) SharedSecretSize() int {
return prv.params.SharedSecretSize return prv.Params.SharedSecretSize
} }
// Import clears content of the private key currently stored in the structure // Import clears content of the private key currently stored in the structure
@ -188,13 +188,13 @@ func (prv *PrivateKey) Import(input []byte) error {
func (prv *PrivateKey) Generate(rand io.Reader) error { func (prv *PrivateKey) Generate(rand io.Reader) error {
var dp *common.DomainParams var dp *common.DomainParams
if (prv.keyVariant & KeyVariantSidhA) == KeyVariantSidhA { if (prv.KeyVariant & KeyVariantSidhA) == KeyVariantSidhA {
dp = &prv.params.A dp = &prv.Params.A
} else { } else {
dp = &prv.params.B dp = &prv.Params.B
} }
if prv.keyVariant == KeyVariantSike { if prv.KeyVariant == KeyVariantSike {
if _, err := io.ReadFull(rand, prv.S); err != nil { if _, err := io.ReadFull(rand, prv.S); err != nil {
return err return err
} }
@ -222,13 +222,13 @@ func (prv *PrivateKey) Generate(rand io.Reader) error {
// Generates public key. // Generates public key.
func (prv *PrivateKey) GeneratePublicKey(pub *PublicKey) { func (prv *PrivateKey) GeneratePublicKey(pub *PublicKey) {
var isA = (prv.keyVariant & KeyVariantSidhA) == KeyVariantSidhA var isA = (prv.KeyVariant & KeyVariantSidhA) == KeyVariantSidhA
if (pub.keyVariant != prv.keyVariant) || (pub.params.ID != prv.params.ID) { if (pub.KeyVariant != prv.KeyVariant) || (pub.Params.ID != prv.Params.ID) {
panic("sidh: incompatbile public key") panic("sidh: incompatbile public key")
} }
switch prv.params.ID { switch prv.Params.ID {
case Fp434: case Fp434:
if isA { if isA {
p434.PublicKeyGenA(&pub.affine3Pt, prv.Scalar) p434.PublicKeyGenA(&pub.affine3Pt, prv.Scalar)
@ -258,13 +258,13 @@ func (prv *PrivateKey) GeneratePublicKey(pub *PublicKey) {
// //
// Caller must make sure key SIDH key pair is not used more than once. // Caller must make sure key SIDH key pair is not used more than once.
func (prv *PrivateKey) DeriveSecret(ss []byte, pub *PublicKey) { func (prv *PrivateKey) DeriveSecret(ss []byte, pub *PublicKey) {
var isA = (prv.keyVariant & KeyVariantSidhA) == KeyVariantSidhA var isA = (prv.KeyVariant & KeyVariantSidhA) == KeyVariantSidhA
if (pub.keyVariant == prv.keyVariant) || (pub.params.ID != prv.params.ID) { if (pub.KeyVariant == prv.KeyVariant) || (pub.Params.ID != prv.Params.ID) {
panic("sidh: public and private are incompatbile") panic("sidh: public and private are incompatbile")
} }
switch prv.params.ID { switch prv.Params.ID {
case Fp434: case Fp434:
if isA { if isA {
p434.DeriveSecretA(ss, prv.Scalar, &pub.affine3Pt) p434.DeriveSecretA(ss, prv.Scalar, &pub.affine3Pt)

View File

@ -60,7 +60,7 @@ func (c *KEM) Encapsulate(ciphertext, secret []byte, pub *PublicKey) error {
panic("KEM unallocated") panic("KEM unallocated")
} }
if KeyVariantSike != pub.keyVariant { if KeyVariantSike != pub.KeyVariant {
panic("Wrong type of public key") panic("Wrong type of public key")
} }
@ -80,9 +80,9 @@ func (c *KEM) Encapsulate(ciphertext, secret []byte, pub *PublicKey) error {
var buf [3 * common.MaxSharedSecretBsz]byte var buf [3 * common.MaxSharedSecretBsz]byte
var skA = PrivateKey{ var skA = PrivateKey{
key: key{ Key: Key{
params: c.params, Params: c.params,
keyVariant: KeyVariantSidhA}, KeyVariant: KeyVariantSidhA},
Scalar: c.secretBytes} Scalar: c.secretBytes}
var pkA = NewPublicKey(c.params.ID, KeyVariantSidhA) var pkA = NewPublicKey(c.params.ID, KeyVariantSidhA)
@ -114,11 +114,11 @@ func (c *KEM) Decapsulate(secret []byte, prv *PrivateKey, pub *PublicKey, cipher
panic("KEM unallocated") panic("KEM unallocated")
} }
if KeyVariantSike != pub.keyVariant { if KeyVariantSike != pub.KeyVariant {
panic("Wrong type of public key") panic("Wrong type of public key")
} }
if pub.keyVariant != prv.keyVariant { if pub.KeyVariant != prv.KeyVariant {
panic("Public and private key are of different type") panic("Public and private key are of different type")
} }
@ -134,9 +134,9 @@ func (c *KEM) Decapsulate(secret []byte, prv *PrivateKey, pub *PublicKey, cipher
var r [common.MaxSidhPrivateKeyBsz]byte var r [common.MaxSidhPrivateKeyBsz]byte
var pkBytes [3 * common.MaxSharedSecretBsz]byte var pkBytes [3 * common.MaxSharedSecretBsz]byte
var skA = PrivateKey{ var skA = PrivateKey{
key: key{ Key: Key{
params: c.params, Params: c.params,
keyVariant: KeyVariantSidhA}, KeyVariant: KeyVariantSidhA},
Scalar: c.secretBytes} Scalar: c.secretBytes}
var pkA = NewPublicKey(c.params.ID, KeyVariantSidhA) var pkA = NewPublicKey(c.params.ID, KeyVariantSidhA)
c1Len, err := c.decrypt(m[:], prv, ciphertext) c1Len, err := c.decrypt(m[:], prv, ciphertext)
@ -166,7 +166,7 @@ func (c *KEM) Decapsulate(secret []byte, prv *PrivateKey, pub *PublicKey, cipher
// //
// See more details in "On the security of supersingular isogeny cryptosystems" // See more details in "On the security of supersingular isogeny cryptosystems"
// (S. Galbraith, et al., 2016, ePrint #859). // (S. Galbraith, et al., 2016, ePrint #859).
mask := subtle.ConstantTimeCompare(pkBytes[:c.params.PublicKeySize], ciphertext[:pub.params.PublicKeySize]) mask := subtle.ConstantTimeCompare(pkBytes[:c.params.PublicKeySize], ciphertext[:pub.Params.PublicKeySize])
common.Cpick(mask, m[:c1Len], m[:c1Len], prv.S) common.Cpick(mask, m[:c1Len], m[:c1Len], prv.S)
c.shake.Reset() c.shake.Reset()
_, _ = c.shake.Write(m[:c1Len]) _, _ = c.shake.Write(m[:c1Len])
@ -201,11 +201,11 @@ func (c *KEM) SharedSecretSize() int {
func (c *KEM) generateCiphertext(ctext []byte, skA *PrivateKey, pkA, pkB *PublicKey, ptext []byte) { func (c *KEM) generateCiphertext(ctext []byte, skA *PrivateKey, pkA, pkB *PublicKey, ptext []byte) {
var n [common.MaxMsgBsz]byte var n [common.MaxMsgBsz]byte
var j [common.MaxSharedSecretBsz]byte var j [common.MaxSharedSecretBsz]byte
var ptextLen = skA.params.MsgLen var ptextLen = skA.Params.MsgLen
skA.DeriveSecret(j[:], pkB) skA.DeriveSecret(j[:], pkB)
c.shake.Reset() c.shake.Reset()
_, _ = c.shake.Write(j[:skA.params.SharedSecretSize]) _, _ = c.shake.Write(j[:skA.Params.SharedSecretSize])
_, _ = c.shake.Read(n[:ptextLen]) _, _ = c.shake.Read(n[:ptextLen])
for i := range ptext { for i := range ptext {
n[i] ^= ptext[i] n[i] ^= ptext[i]
@ -221,12 +221,12 @@ func (c *KEM) generateCiphertext(ctext []byte, skA *PrivateKey, pkA, pkB *Public
func (c *KEM) encrypt(ctext []byte, rng io.Reader, pub *PublicKey, ptext []byte) error { func (c *KEM) encrypt(ctext []byte, rng io.Reader, pub *PublicKey, ptext []byte) error {
var ptextLen = len(ptext) var ptextLen = len(ptext)
// c1 must be security level + 64 bits (see [SIKE] 1.4 and 4.3.3) // c1 must be security level + 64 bits (see [SIKE] 1.4 and 4.3.3)
if ptextLen != pub.params.KemSize { if ptextLen != pub.Params.KemSize {
return errors.New("unsupported message length") return errors.New("unsupported message length")
} }
skA := NewPrivateKey(pub.params.ID, KeyVariantSidhA) skA := NewPrivateKey(pub.Params.ID, KeyVariantSidhA)
pkA := NewPublicKey(pub.params.ID, KeyVariantSidhA) pkA := NewPublicKey(pub.Params.ID, KeyVariantSidhA)
err := skA.Generate(rng) err := skA.Generate(rng)
if err != nil { if err != nil {
return err return err
@ -243,17 +243,17 @@ func (c *KEM) encrypt(ctext []byte, rng io.Reader, pub *PublicKey, ptext []byte)
func (c *KEM) decrypt(n []byte, prv *PrivateKey, ctext []byte) (int, error) { func (c *KEM) decrypt(n []byte, prv *PrivateKey, ctext []byte) (int, error) {
var c1Len int var c1Len int
var j [common.MaxSharedSecretBsz]byte var j [common.MaxSharedSecretBsz]byte
var pkLen = prv.params.PublicKeySize var pkLen = prv.Params.PublicKeySize
// ctext is a concatenation of (ciphertext = pubkey_A || c1) // ctext is a concatenation of (ciphertext = pubkey_A || c1)
// it must be security level + 64 bits (see [SIKE] 1.4 and 4.3.3) // it must be security level + 64 bits (see [SIKE] 1.4 and 4.3.3)
// Lengths has been already checked by Decapsulate() // Lengths has been already checked by Decapsulate()
c1Len = len(ctext) - pkLen c1Len = len(ctext) - pkLen
c0 := NewPublicKey(prv.params.ID, KeyVariantSidhA) c0 := NewPublicKey(prv.Params.ID, KeyVariantSidhA)
err := c0.Import(ctext[:pkLen]) err := c0.Import(ctext[:pkLen])
prv.DeriveSecret(j[:], c0) prv.DeriveSecret(j[:], c0)
c.shake.Reset() c.shake.Reset()
_, _ = c.shake.Write(j[:prv.params.SharedSecretSize]) _, _ = c.shake.Write(j[:prv.Params.SharedSecretSize])
_, _ = c.shake.Read(n[:c1Len]) _, _ = c.shake.Read(n[:c1Len])
for i := range n[:c1Len] { for i := range n[:c1Len] {
n[i] ^= ctext[pkLen+i] n[i] ^= ctext[pkLen+i]