-
Notifications
You must be signed in to change notification settings - Fork 0
/
opsfkem.go
103 lines (83 loc) · 2.08 KB
/
opsfkem.go
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
96
97
98
99
100
101
102
103
package OPFSKEM
import (
"crypto/sha256"
"errors"
"fmt"
"hibkem"
"io"
"ots"
)
type PK struct {
mpk *HIBKEM.Params
otp *OTS.Params
}
type SK = []*HIBKEM.PrivateKey
type Ciphertext struct {
ctibkem *HIBKEM.Ciphertext
sig *OTS.Signature
vk *OTS.VerKey
}
type Key = *HIBKEM.SessionKey
////////////////////////
func KGen(r io.Reader, l int) (*PK, SK, error) {
pk := &PK{}
var err error
msk := &HIBKEM.PrivateKey{}
if pk.mpk, msk, err = HIBKEM.Setup(r, l); err != nil {
return nil, nil, err
}
if pk.otp, err = OTS.Setup(r); err != nil {
return nil, nil, err
}
return pk, SK{msk}, nil
}
func Enc(r io.Reader, pk *PK, t string) (Key, *Ciphertext, error) {
ct := &Ciphertext{}
var symkey Key
vk, sk, err := pk.otp.KeyGen(r)
if err != nil {
return nil, nil, err
}
idstr := pk.mpk.RootID + t + SHA256ToBin(vk.Marshal())
if symkey, ct.ctibkem, err = HIBKEM.Encapsulate(r, pk.mpk, idstr); err != nil {
return nil, nil, err
}
if ct.sig, err = sk.Sign(r, ct.ctibkem.Marshal()); err != nil {
return nil, nil, err
}
ct.vk = vk
return symkey, ct, nil
}
func PnctCxt(pk *PK, sk SK, t string, ct *Ciphertext) (SK, SK) {
idstr := pk.mpk.RootID + t + SHA256ToBin(ct.vk.Marshal())
return HIBKEM.PunctureTree(pk.mpk, sk, idstr)
}
func PnctInt(pk *PK, sk SK, t string) (SK, SK) {
return HIBKEM.PunctureTree(pk.mpk, sk, pk.mpk.RootID+t)
}
func Dec(r io.Reader, pk *PK, sk SK, t string, ct *Ciphertext) (Key, error) {
if !ct.sig.Verify(pk.otp, ct.vk, ct.ctibkem.Marshal()) {
return nil, errors.New("Ill-formed ciphertext!")
}
idstr := pk.mpk.RootID + t + SHA256ToBin(ct.vk.Marshal())
for _, item := range sk {
if idstr == item.ID {
return HIBKEM.Decapsulate(item, ct.ctibkem), nil
}
if HIBKEM.IsAncestor(item.ID, idstr) {
tempsk, err := HIBKEM.KeyGen(r, pk.mpk, item, idstr)
if err != nil {
return nil, err
}
return HIBKEM.Decapsulate(tempsk, ct.ctibkem), nil
}
}
return nil, errors.New("Decrypt error!")
}
func SHA256ToBin(s []byte) string {
idstr := ""
for _, b := range sha256.Sum256(s) {
idstr += fmt.Sprintf("%08b", b)
}
return idstr
}