-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcontext.go
More file actions
95 lines (84 loc) · 2.73 KB
/
context.go
File metadata and controls
95 lines (84 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package mbpqs
import (
"fmt"
)
// Context including a full MBPQS instance.
type Context struct {
params *Params // MBPQS parameters
wotsLogW uint8 // logarithm of the Winternitz parameter
wotsLen1 uint32 // WOTS+ chains for message
wotsLen2 uint32 // WOTS+ chains for checksum
wotsLen uint32 // total number of WOTS+ chains
wotsSigBytes uint32 // length of WOTS+ signature
// The amount of threads to use in the MBPQS scheme.
threads int
}
// Allocates memory for a Context and sets the given parameters in it.
func newContext(p *Params) (ctx *Context, err error) {
ctx = new(Context)
if p.n != 32 && p.n != 64 {
return nil, fmt.Errorf("Only n=32 and n = 64 are supported for now (it was %d)", p.n)
}
if p.w != 4 && p.w != 16 && p.w != 256 {
return nil, fmt.Errorf("w = {4,16,256} are suported, no other values (w was %d)", p.w)
}
if p.rootH > 32 {
return nil, fmt.Errorf("the maxmimum root tree height is 32")
}
if p.chanH < 2 {
return nil, fmt.Errorf("minimum value for h = 2 (tree with 2 leafs)")
}
if p.c > uint16(p.chanH-1) {
return nil, fmt.Errorf("maximum value for c = h - 1")
}
ctx.params = p
ctx.wotsLogW = p.wotsLogW()
ctx.wotsLen1 = p.wotsLen1()
ctx.wotsLen2 = p.wotsLen2()
ctx.wotsLen = p.wotsLen()
ctx.wotsSigBytes = p.wotsSignatureSize()
return ctx, nil
}
// Derive a keypair given for a context and n-byte random seeds skSeed, pubSeed, and skPrf.
func (ctx *Context) deriveKeyPair(skSeed, skPrf, pubSeed []byte) (
*PrivateKey, *PublicKey, error) {
if len(pubSeed) != int(ctx.params.n) || len(skSeed) != int(ctx.params.n) || len(skPrf) != int(ctx.params.n) {
return nil, nil, fmt.Errorf("skPrf, skSeed and pubSeed should have length %d", ctx.params.n)
}
pad := ctx.newScratchPad()
sk, err := ctx.newPrivateKey(pad, skSeed, pubSeed, skPrf, 0)
if err != nil {
return nil, nil, err
}
pk := sk.derivePublicKey()
if err != nil {
return nil, nil, err
}
return sk, pk, nil
}
// Generate a privateKey for a context and n-byte random seeds skSeed, pubSeed, and skPrf.
func (ctx *Context) newPrivateKey(pad scratchPad, skSeed, pubSeed, skPrf []byte, seqNo SignatureSeqNo) (*PrivateKey, error) {
ret := PrivateKey{
seqNo: 0,
skSeed: skSeed,
skPrf: skPrf,
pubSeed: pubSeed,
ctx: ctx,
ph: ctx.precomputeHashes(pubSeed, skSeed),
}
// Create a root tree to retrieve the root.
rt := ctx.genRootTree(pad, ret.ph)
ret.root = make([]byte, ctx.params.n)
copy(ret.root, rt.getRootNode())
return &ret, nil
}
// Return the MBPQS PublicKey derived from this PrivateKey.
func (sk *PrivateKey) derivePublicKey() *PublicKey {
ret := PublicKey{
ctx: sk.ctx,
pubSeed: sk.pubSeed,
ph: sk.ctx.precomputeHashes(sk.pubSeed, nil),
root: sk.root,
}
return &ret
}