mirror of
https://github.com/henrydcase/nobs.git
synced 2024-11-22 15:18:57 +00:00
export more symbols from common
This commit is contained in:
parent
a152c09fd5
commit
2500d74484
@ -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[:]) {
|
||||||
|
@ -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)
|
||||||
|
@ -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]
|
||||||
|
Loading…
Reference in New Issue
Block a user