1
0
mirror of https://github.com/henrydcase/nobs.git synced 2024-11-22 23:28:57 +00:00
nobs/kem/mkem/csidh.go

109 lines
2.0 KiB
Go
Raw Normal View History

2020-08-25 11:19:07 +01:00
package mkem
import (
"github.com/henrydcase/nobs/dh/csidh"
"github.com/henrydcase/nobs/drbg"
"github.com/henrydcase/nobs/hash/sha3"
)
const (
SharedSecretSz = 64
PublicKeySz = 64
)
2020-08-25 11:19:07 +01:00
// Used for storing cipertext
2020-08-25 11:19:07 +01:00
type ciphertext struct {
// public key
U [64]byte
// private key
V [64]byte
2020-08-25 11:19:07 +01:00
}
type PKE struct {
Rng *drbg.CtrDrbg
H sha3.ShakeHash
2020-08-25 11:19:07 +01:00
}
type MultiPKE struct {
PKE
// stores ephemeral/internal public key
Ct0 [PublicKeySz]byte
// stores list of ciphertexts ct[i]
Cts [][SharedSecretSz]byte
2020-08-25 11:19:07 +01:00
}
// Allocates PKE
func (c *PKE) Allocate(rng *drbg.CtrDrbg) {
c.Rng = rng
2020-08-25 11:19:07 +01:00
// Function H used in Algorithm 16 and 18
c.H = sha3.NewShake128()
2020-08-25 11:19:07 +01:00
}
// Allocates MultiPKE
func (c *MultiPKE) Allocate(recipients_nb uint, rng *drbg.CtrDrbg) {
c.PKE.Allocate(rng)
c.Cts = make([][SharedSecretSz]byte, recipients_nb)
2020-08-25 11:19:07 +01:00
}
// PKE encryption
func (c *PKE) Enc(pk *csidh.PublicKey, pt *[16]byte) (ct ciphertext) {
2020-08-25 11:19:07 +01:00
var ss [64]byte
var pkA csidh.PublicKey
var skA csidh.PrivateKey
csidh.GeneratePrivateKey(&skA, c.Rng)
csidh.DeriveSecret(&ss, pk, &skA, c.Rng)
2020-08-25 11:19:07 +01:00
c.H.Reset()
c.H.Write(ss[:])
c.H.Read(ss[:16])
for i := 0; i < 16; i++ {
ct.V[i] = pt[i] ^ ss[i]
2020-08-25 11:19:07 +01:00
}
csidh.GeneratePublicKey(&pkA, &skA, c.Rng)
pkA.Export(ct.U[:])
2020-08-25 11:19:07 +01:00
return
}
// PKE decryption
func (c *PKE) Dec(sk *csidh.PrivateKey, ct *ciphertext) (pt [16]byte) {
2020-08-25 11:19:07 +01:00
var ss [64]byte
var pk csidh.PublicKey
pk.Import(ct.U[:])
csidh.DeriveSecret(&ss, &pk, sk, c.Rng)
c.H.Reset()
c.H.Write(ss[:])
c.H.Read(ss[:16])
for i := 0; i < 16; i++ {
pt[i] = ct.V[i] ^ ss[i]
2020-08-25 11:19:07 +01:00
}
return
}
// mPKE encryption
func (c *MultiPKE) Encrypt(keys []csidh.PublicKey, pt *[16]byte) {
2020-08-25 11:19:07 +01:00
var ss [64]byte
var pkA csidh.PublicKey
var skA csidh.PrivateKey
csidh.GeneratePrivateKey(&skA, c.Rng)
for i, pk := range keys {
csidh.DeriveSecret(&ss, &pk, &skA, c.Rng)
c.H.Write(ss[:])
c.H.Read(ss[:16])
c.H.Reset()
for j := 0; j < 16; j++ {
c.Cts[i][j] = pt[j] ^ ss[j]
2020-08-25 11:19:07 +01:00
}
}
csidh.GeneratePublicKey(&pkA, &skA, c.Rng)
pkA.Export(c.Ct0[:])
2020-08-25 11:19:07 +01:00
return
}