github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/chat/flip/secret.go (about) 1 package flip 2 3 import ( 4 "crypto/hmac" 5 "crypto/rand" 6 "crypto/sha256" 7 "fmt" 8 "sort" 9 10 chat1 "github.com/keybase/client/go/protocol/chat1" 11 gregor1 "github.com/keybase/client/go/protocol/gregor1" 12 ) 13 14 func (s *Secret) XOR(t Secret) *Secret { 15 for i, b := range t { 16 s[i] = b ^ s[i] 17 } 18 return s 19 } 20 21 func (s Secret) IsNil() bool { 22 return bytesAreNil(s[:]) 23 } 24 25 func bytesAreNil(v []byte) bool { 26 for _, b := range v { 27 if b != byte(0) { 28 return false 29 } 30 } 31 return true 32 } 33 34 func (s Secret) Hash() Secret { 35 h := sha256.New() 36 _, err := h.Write(s[:]) 37 if err != nil { 38 panic(err) 39 } 40 tmp := h.Sum(nil) 41 var ret Secret 42 copy(ret[:], tmp) 43 return ret 44 } 45 46 func (s Secret) Eq(t Secret) bool { 47 return hmac.Equal(s[:], t[:]) 48 } 49 50 type CommitmentPayload struct { 51 _struct bool `codec:",toarray"` //nolint 52 V Version `codec:"v" json:"v"` 53 U gregor1.UID `codec:"u" json:"u"` 54 D gregor1.DeviceID `codec:"d" json:"d"` 55 C chat1.ConversationID `codec:"c" json:"c"` 56 G chat1.FlipGameID `codec:"i" json:"i"` 57 S Time `codec:"s" json:"s"` 58 } 59 60 func (s Secret) computeCommitment(cp CommitmentPayload) (Commitment, error) { 61 var ret Commitment 62 hm := hmac.New(sha256.New, s[:]) 63 raw, err := msgpackEncode(cp) 64 if err != nil { 65 return ret, err 66 } 67 _, err = hm.Write(raw) 68 if err != nil { 69 panic(err) 70 } 71 tmp := hm.Sum(nil) 72 copy(ret[:], tmp) 73 return ret, nil 74 } 75 76 func (c Commitment) Eq(d Commitment) bool { 77 return hmac.Equal(c[:], d[:]) 78 } 79 80 func GenerateSecret() Secret { 81 var ret Secret 82 n, err := rand.Read(ret[:]) 83 if n != len(ret) { 84 panic("failed to generate secret; short random read") 85 } 86 if err != nil { 87 panic(fmt.Sprintf("failed to generated secret: %s", err.Error())) 88 } 89 return ret 90 } 91 92 func checkUserDeviceCommitments(v []UserDeviceCommitment) bool { 93 for i := 1; i < len(v); i++ { 94 if !v[i-1].Ud.LessThan(v[i].Ud) { 95 return false 96 } 97 } 98 return true 99 } 100 101 func sortUserDeviceCommitments(v []UserDeviceCommitment) { 102 if !checkUserDeviceCommitments(v) { 103 sort.Slice(v, func(i, j int) bool { return v[i].Ud.LessThan(v[j].Ud) }) 104 } 105 } 106 107 func hashUserDeviceCommitments(v []UserDeviceCommitment) (Hash, error) { 108 var ret Hash 109 sortUserDeviceCommitments(v) 110 raw, err := msgpackEncode(v) 111 if err != nil { 112 return ret, err 113 } 114 h := sha256.New() 115 _, err = h.Write(raw) 116 if err != nil { 117 panic(err) 118 } 119 tmp := h.Sum(nil) 120 copy(ret[:], tmp) 121 return ret, nil 122 }