(uint64(buf[6]) << 8) |
uint64(buf[7])
default:
- for i := 0; i < len(buf); i++ {
+ for i := range len(buf) {
v |= uint64(buf[i]) << ((len(buf) - i - 1) * 8)
}
}
buf[1] = byte((v & 0x00FF000000000000) >> 48)
buf[0] = byte((v & 0xFF00000000000000) >> 56)
default:
- for i := 0; i < len(buf); i++ {
+ for i := range len(buf) {
buf[i] = byte((v & (0xFF << ((len(buf) - i - 1) * 8)) >> ((len(buf) - i - 1) * 8)) & 0xFF)
}
}
}
func printer(iter *keks.Iterator, count int, inList, inMap bool) {
- for i := 0; i < count; i++ {
+ for i := range count {
if !iter.Next() {
panic("unexpected")
}
if len(our) != their {
log.Fatalln("MAP len differs:", our, their)
}
- for i := 0; i < their; i++ {
+ for range their {
fields = getFields()
k := string(mustDecodeHex(fields[1]))
item, ok := our[k]
}
}
} else {
- for i := 0; i < vv.Len(); i++ {
+ for i := range vv.Len() {
n64, err = Encode(w, vv.Index(i).Interface(), opts)
written += n64
if err != nil {
module go.cypherpunks.su/keks
-go 1.22
+go 1.24
require go.cypherpunks.su/tai64n/v4 v4.1.0
require (
github.com/google/uuid v1.6.0
github.com/mitchellh/mapstructure v1.5.0
+ golang.org/x/term v0.27.0
)
-require (
- golang.org/x/sys v0.28.0 // indirect
- golang.org/x/term v0.27.0 // indirect
-)
+require golang.org/x/sys v0.28.0 // indirect
import (
"bytes"
"crypto/ecdh"
+ "crypto/hkdf"
"crypto/rand"
"errors"
"flag"
"go.cypherpunks.su/balloon/v3"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/chacha20poly1305"
- "golang.org/x/crypto/hkdf"
- "golang.org/x/crypto/sha3"
"golang.org/x/term"
"go.cypherpunks.su/keks"
"go.cypherpunks.su/keks/pki"
+ pkihash "go.cypherpunks.su/keks/pki/hash"
"go.cypherpunks.su/keks/pki/utils"
"go.cypherpunks.su/keks/types"
)
return h
}
-func shake256() hash.Hash {
- return sha3.NewShake256()
-}
-
func readPasswd(prompt string) (passwd []byte) {
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
}
passwd := readPasswd("Passphrase:")
{
- kek := hkdf.Extract(blake2b256, balloon.H(blake2b256,
+ var kek []byte
+ kek, err = hkdf.Extract(blake2b256, balloon.H(blake2b256,
passwd,
append(encrypted.Bind[:], *kem.Salt...),
int(kem.Cost.S), int(kem.Cost.T), int(kem.Cost.P),
), []byte(BalloonHKDFSalt))
+ if err != nil {
+ log.Fatal(err)
+ }
var cekp []byte
cekp, err = kemChaPolyOpen(kek, kem.CEK, chacha20poly1305.KeySize)
if err != nil {
*kem.Encap, pub,
keySNTRUP[:], keyX25519,
}, []byte{})
- kek := hkdf.Extract(blake2b256,
+ var kek []byte
+ kek, err = hkdf.Extract(blake2b256,
ikm, []byte(SNTRUP4591761X25519Salt))
+ if err != nil {
+ log.Fatal(err)
+ }
var cekp []byte
cekp, err = kemChaPolyOpen(kek, kem.CEK, chacha20poly1305.KeySize)
if err != nil {
*kem.Encap, pub,
keyMcEliece, keyX25519,
}, []byte{})
- kek := hkdf.Extract(shake256,
+ var kek []byte
+ kek, err = hkdf.Extract(pkihash.NewSHAKE256,
ikm, []byte(ClassicMcEliece6960119X25519Salt))
+ if err != nil {
+ log.Fatal(err)
+ }
var cekp []byte
cekp, err = kemChaPolyOpen(
kek[:chacha20poly1305.KeySize],
},
}
{
- kek := hkdf.Extract(blake2b256, balloon.H(blake2b256,
+ var kek []byte
+ kek, err = hkdf.Extract(blake2b256, balloon.H(blake2b256,
passwd,
append(binding[:], salt...),
*balloonS, *balloonT, *balloonP,
), []byte(BalloonHKDFSalt))
+ if err != nil {
+ log.Fatal(err)
+ }
kem.CEK, err = kemChaPolySeal(kek, cek)
if err != nil {
log.Fatal(err)
encap, pub.V,
keySNTRUP[:], keyX25519,
}, []byte{})
- kek := hkdf.Extract(blake2b256,
+ var kek []byte
+ kek, err = hkdf.Extract(blake2b256,
ikm, []byte(SNTRUP4591761X25519Salt))
+ if err != nil {
+ log.Fatal(err)
+ }
kem.CEK, err = kemChaPolySeal(kek, cek)
if err != nil {
log.Fatal(err)
encap, pub.V,
keyMcEliece[:], keyX25519,
}, []byte{})
- kek := hkdf.Extract(shake256,
+ var kek []byte
+ kek, err = hkdf.Extract(pkihash.NewSHAKE256,
ikm, []byte(ClassicMcEliece6960119X25519Salt))
+ if err != nil {
+ log.Fatal(err)
+ }
kem.CEK, err = kemChaPolySeal(kek[:chacha20poly1305.KeySize], cek)
if err != nil {
log.Fatal(err)
module go.cypherpunks.su/keks/pki
-go 1.22
+go 1.24
require (
github.com/google/uuid v1.6.0
"go.cypherpunks.su/gogost/v6/gost34112012256"
"go.cypherpunks.su/gogost/v6/gost34112012512"
"golang.org/x/crypto/blake2b"
- "golang.org/x/crypto/sha3"
ed25519blake2b "go.cypherpunks.su/keks/pki/ed25519-blake2b"
"go.cypherpunks.su/keks/pki/gost"
}
return h
case SHAKE128:
- return sha3.NewShake128()
+ return NewSHAKE128()
case SHAKE256:
- return sha3.NewShake256()
+ return NewSHAKE256()
case SHAKE128Merkle:
return NewSHAKE128MerkleHasher(
merkle.DefaultChunkLen, runtime.NumCPU())
chunkLen: chunkLen,
}
hashSize := h.Size()
- for i := 0; i < 2*maxDepth; i++ {
+ for i := range 2 * maxDepth {
h.hashes[i] = make([]byte, hashSize)
h.frees[i] = true
}
func (h *Hasher) Reset() {
h.pw.Close()
<-h.finished
- for i := 0; i < 2*maxDepth; i++ {
+ for i := range 2 * maxDepth {
h.frees[i] = true
}
h.prepare()
func (h *Hasher) fold() {
var err error
- for l := 0; l < maxDepth; l++ {
+ for l := range maxDepth {
if h.frees[l*2+0] || h.frees[l*2+1] {
continue
}
package hash
import (
+ "crypto/sha3"
"hash"
+ "io"
"go.cypherpunks.su/keks/pki/hash/merkle"
- "golang.org/x/crypto/sha3"
)
+type SHAKE struct {
+ xof *sha3.SHAKE
+ l int
+}
+
+func (h SHAKE) Size() int {
+ return h.l
+}
+
+func (h SHAKE) BlockSize() int {
+ return h.xof.BlockSize()
+}
+
+func (h SHAKE) Reset() {
+ h.xof.Reset()
+}
+
+func (h SHAKE) Write(p []byte) (int, error) {
+ return h.xof.Write(p)
+}
+
+func (h SHAKE) Sum(b []byte) []byte {
+ buf := make([]byte, h.l)
+ if _, err := io.ReadFull(h.xof, buf); err != nil {
+ panic(err)
+ }
+ return append(b, buf...)
+}
+
+func NewSHAKE128() hash.Hash {
+ return SHAKE{xof: sha3.NewSHAKE128(), l: 32}
+}
+
+func NewSHAKE256() hash.Hash {
+ return SHAKE{xof: sha3.NewSHAKE256(), l: 32}
+}
+
+func NewCSHAKE128(s []byte) hash.Hash {
+ return SHAKE{xof: sha3.NewCSHAKE128(nil, s), l: 32}
+}
+
+func NewCSHAKE256(s []byte) hash.Hash {
+ return SHAKE{xof: sha3.NewCSHAKE256(nil, s), l: 32}
+}
+
func NewSHAKE128MerkleHasher(chunkLen, workers int) hash.Hash {
- leafHash := sha3.NewCShake128(nil, []byte(merkle.Leaf))
- nodeHash := sha3.NewCShake128(nil, []byte(merkle.Node))
return merkle.NewHasher(
- func() hash.Hash { return leafHash.Clone() },
- func() hash.Hash { return nodeHash.Clone() },
- func(hash.Hash) hash.Hash { return leafHash.Clone() },
- func(hash.Hash) hash.Hash { return nodeHash.Clone() },
+ func() hash.Hash { return NewCSHAKE128([]byte(merkle.Leaf)) },
+ func() hash.Hash { return NewCSHAKE128([]byte(merkle.Node)) },
+ func(h hash.Hash) hash.Hash {
+ h.Reset()
+ return h
+ },
+ func(h hash.Hash) hash.Hash {
+ h.Reset()
+ return h
+ },
chunkLen,
workers,
)
}
func NewSHAKE256MerkleHasher(chunkLen, workers int) hash.Hash {
- leafHash := sha3.NewCShake256(nil, []byte(merkle.Leaf))
- nodeHash := sha3.NewCShake256(nil, []byte(merkle.Node))
return merkle.NewHasher(
- func() hash.Hash { return leafHash.Clone() },
- func() hash.Hash { return nodeHash.Clone() },
- func(hash.Hash) hash.Hash { return leafHash.Clone() },
- func(hash.Hash) hash.Hash { return nodeHash.Clone() },
+ func() hash.Hash { return NewCSHAKE256([]byte(merkle.Leaf)) },
+ func() hash.Hash { return NewCSHAKE256([]byte(merkle.Node)) },
+ func(h hash.Hash) hash.Hash {
+ h.Reset()
+ return h
+ },
+ func(h hash.Hash) hash.Hash {
+ h.Reset()
+ return h
+ },
chunkLen,
workers,
)
module go.cypherpunks.su/keks/pki/sntrup4591761-x25519
-go 1.22
+go 1.24
require github.com/companyzero/sntrup4591761 v0.0.0-20220309191932-9e0f3af2f07a
using BLAKE2b hash with 128 or 256 bit output length specified.
@node cer-mceliece6960119-x25519
-@subsection cer with Classic McEliece 6960119+x25519
+@subsection cer with Classic McEliece 6960-119+x25519
-Certificate with combined Classic McEliece 6960119 and Curve25519
+Certificate with combined Classic McEliece 6960-119 and Curve25519
public keys is used for KEM purposes, so should have "kem" key usage set.
Its algorithm identifier is @code{mceliece6960119-x25519}. Its public key
-value is a concatenation of 1047319-byte mceliece6960119 public key and
-32-byte Curve25519 one.
+value is a concatenation of 1047319-byte @code{mceliece6960119} public key
+and 32-byte Curve25519 one.
Public key's identifier and @code{cid} should be calculated
using either SHAKE128 or SHAKE256 hash.