gitee.com/lh-her-team/common@v1.5.1/crypto/bulletproofs/bulletproofs_cgo/commitment.go (about) 1 //+build linux,amd64 2 3 /* 4 Pedersen commitment is a commitment scheme which bindingly hides a value with a randomness (called opening). This commitment scheme has two major properties: hiding and binding. 5 Hiding: given a commitment, it is hard to guess the right value committed to it. 6 Binding: given a commitment, the value committed to it, and the opening, it is hard to find another value-opening pair for the commitment. 7 A commitment can be opened. This does not mean that the committed value can be extracted from it like a decryption on a ciphertext. It means that with the opening and the value, the validity of this commitment can be verified. 8 */ 9 10 package bulletproofs_cgo 11 12 //#cgo CFLAGS: -g -O2 -pthread -I./c_include 13 //#cgo LDFLAGS: -L./c_lib -lbulletproofs -lm -L/usr/lib/x86_64-linux-gnu -ldl 14 //#cgo LDFLAGS: -L/usr/bin/ld -lpthread 15 //#include <stdlib.h> 16 //#include <stdio.h> 17 //#include <string.h> 18 //#include <bulletproofs.h> 19 import "C" 20 import ( 21 "fmt" 22 "unsafe" 23 ) 24 25 // PedersenRNG generate a truly random scalar (which can be used as an opening to generate a commitment). 26 // return: a random scalar in []byte format 27 func PedersenRNG() ([]byte, error) { 28 var r [POINT_SIZE]byte 29 randomness := r[:] 30 ret := C.bulletproofs_generate_random_scalar(unsafe.Pointer(&randomness[0])) 31 if ret != OK { 32 return nil, fmt.Errorf("fail to generate random scalar: " + getErrMsg(int64(ret))) 33 } 34 return randomness, nil 35 } 36 37 // PedersenCommitRandomOpening compute Pedersen commitment on a value x with a randomly chosen opening 38 // x: the value to commit 39 // return1: commitment C = xB + rB' 40 // return2: opening r (randomly picked) 41 func PedersenCommitRandomOpening(x uint64) ([]byte, []byte, error) { 42 var commitment [POINT_SIZE]byte 43 var opening [POINT_SIZE]byte 44 commitmentSlice := commitment[:] 45 openingSlice := opening[:] 46 ret := C.pedersen_commit_with_random_opening(unsafe.Pointer(&commitmentSlice[0]), unsafe.Pointer(&openingSlice[0]), C.uint(x)) 47 if ret != OK { 48 return nil, nil, fmt.Errorf("fail to generate commitment:" + getErrMsg(int64(ret))) 49 } 50 return commitmentSlice, openingSlice, nil 51 } 52 53 // PedersenCommitSpecificOpening compute Pedersen commitment on a value x with a given opening 54 // x: the value to commit 55 // return1: commitment C = xB + rB' 56 func PedersenCommitSpecificOpening(x uint64, r []byte) ([]byte, error) { 57 if len(r) != POINT_SIZE { 58 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": commitment opening length should 32-byte") 59 } 60 var commitment [POINT_SIZE]byte 61 commitmentSlice := commitment[:] 62 ret := C.pedersen_commit_with_specific_opening(unsafe.Pointer(&commitmentSlice[0]), unsafe.Pointer(&r[0]), C.uint(x)) 63 if ret != OK { 64 return nil, fmt.Errorf("fail to generate commitment: " + getErrMsg(int64(ret))) 65 } 66 return commitmentSlice, nil 67 } 68 69 // PedersenVerify verify the validity of a commitment with respect to a value-opening pair 70 // commitment: the commitment to be opened or verified: xB + rB' 71 // opening: the opening of the commitment: r 72 // value: the value claimed being binding to commitment: x 73 // return1: true if commitment is valid, false otherwise 74 func PedersenVerify(commitment, opening []byte, value uint64) (bool, error) { 75 if len(commitment) != POINT_SIZE || len(opening) != POINT_SIZE { 76 return false, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": commitment or opening length should 32-byte") 77 } 78 ret := C.pedersen_verify(unsafe.Pointer(&commitment[0]), unsafe.Pointer(&opening[0]), C.uint(value)) 79 if ret == 1 { 80 return true, nil 81 } 82 return false, nil 83 } 84 85 // PedersenNeg Compute a commitment to -x from a commitment to x without revealing the value x 86 // commitment: C = xB + rB' 87 // value: the value y 88 // return1: the new commitment to x + y: C' = (x + y)B + rB' 89 func PedersenNeg(commitment []byte) ([]byte, error) { 90 if len(commitment) != POINT_SIZE { 91 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": commitment length should 32-byte") 92 } 93 var result [POINT_SIZE]byte 94 resultSlice := result[:] 95 ret := C.pedersen_point_neg(unsafe.Pointer(&resultSlice[0]), unsafe.Pointer(&commitment[0])) 96 if ret != OK { 97 return nil, fmt.Errorf("fail to compute negation: " + getErrMsg(int64(ret))) 98 } 99 return resultSlice, nil 100 } 101 102 // PedersenNegOpening Compute the negation of opening. Openings are big numbers with 256 bits. 103 // opening: the opening r to be negated 104 // return: the result opening: -r 105 func PedersenNegOpening(opening []byte) ([]byte, error) { 106 if len(opening) != POINT_SIZE { 107 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": opening length should 32-byte") 108 } 109 var openingNeg [POINT_SIZE]byte 110 openingSlice := openingNeg[:] 111 ret := C.pedersen_scalar_neg(unsafe.Pointer(&openingSlice[0]), 112 unsafe.Pointer(&opening[0])) 113 if ret != OK { 114 return nil, fmt.Errorf("fail to compute opening negation: " + getErrMsg(int64(ret))) 115 } 116 return openingSlice, nil 117 } 118 119 // PedersenAddNum Compute a commitment to x + y from a commitment to x without revealing the value x, where y is a scalar 120 // commitment: C = xB + rB' 121 // value: the value y 122 // return1: the new commitment to x + y: C' = (x + y)B + rB' 123 func PedersenAddNum(commitment []byte, value uint64) ([]byte, error) { 124 if len(commitment) != POINT_SIZE { 125 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": commitment length should 32-byte") 126 } 127 var result [POINT_SIZE]byte 128 resultSlice := result[:] 129 ret := C.pedersen_commitment_add_num(unsafe.Pointer(&resultSlice[0]), unsafe.Pointer(&commitment[0]), C.uint(value)) 130 if ret != OK { 131 return nil, fmt.Errorf("fail to compute Pedersen addition: " + getErrMsg(int64(ret))) 132 } 133 return resultSlice, nil 134 } 135 136 // PedersenAddCommitment Compute a commitment to x + y from commitments to x and y, without revealing the value x and y 137 // commitment1: commitment to x: Cx = xB + rB' 138 // commitment2: commitment to y: Cy = yB + sB' 139 // return: commitment to x + y: C = (x + y)B + (r + s)B' 140 func PedersenAddCommitment(commitment1, commitment2 []byte) ([]byte, error) { 141 if len(commitment1) != POINT_SIZE || len(commitment2) != POINT_SIZE { 142 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": commitment length should 32-byte") 143 } 144 var commitment [POINT_SIZE]byte 145 commitmentSlice := commitment[:] 146 ret := C.pedersen_point_add(unsafe.Pointer(&commitmentSlice[0]), 147 unsafe.Pointer(&commitment1[0]), 148 unsafe.Pointer(&commitment2[0])) 149 if ret != OK { 150 return nil, fmt.Errorf("fail to compute Pedersen addition: " + getErrMsg(int64(ret))) 151 } 152 return commitmentSlice, nil 153 } 154 155 // PedersenAddOpening Compute the sum of two openings. Openings are big numbers with 256 bits. 156 // opening1, opening2: the two openings r and s to be summed 157 // return: the result opening: r + s 158 func PedersenAddOpening(opening1, opening2 []byte) ([]byte, error) { 159 if len(opening1) != POINT_SIZE || len(opening2) != POINT_SIZE { 160 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": opening length should 32-byte") 161 } 162 var opening [POINT_SIZE]byte 163 openingSlice := opening[:] 164 ret := C.pedersen_scalar_add(unsafe.Pointer(&openingSlice[0]), 165 unsafe.Pointer(&opening1[0]), 166 unsafe.Pointer(&opening2[0])) 167 if ret != OK { 168 return nil, fmt.Errorf("fail to compute opening addition: " + getErrMsg(int64(ret))) 169 } 170 return openingSlice, nil 171 } 172 173 // PedersenAddCommitmentWithOpening Compute a commitment to x + y without revealing the value x and y 174 // commitment1: commitment to x: Cx = xB + rB' 175 // commitment2: commitment to y: Cy = yB + sB' 176 // return1: the new commitment to x + y: C' = (x + y)B + rB' 177 // return2: the new opening r + s 178 func PedersenAddCommitmentWithOpening(commitment1, commitment2, opening1, opening2 []byte) ([]byte, []byte, error) { 179 commitment, err := PedersenAddCommitment(commitment1, commitment2) 180 if err != nil { 181 return nil, nil, err 182 } 183 opening, err := PedersenAddOpening(opening1, opening2) 184 if err != nil { 185 return nil, nil, err 186 } 187 return commitment, opening, nil 188 } 189 190 // PedersenSubNum Compute a commitment to x - y from a commitment to x without revealing the value x, where y is a scalar 191 // commitment: C = xB + rB' 192 // value: the value y 193 // return1: the new commitment to x - y: C' = (x - y)B + rB' 194 func PedersenSubNum(commitment []byte, value uint64) ([]byte, error) { 195 if len(commitment) != POINT_SIZE { 196 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": commitment length should 32-byte") 197 } 198 var result [POINT_SIZE]byte 199 resultSlice := result[:] 200 ret := C.pedersen_commitment_sub_num(unsafe.Pointer(&resultSlice[0]), unsafe.Pointer(&commitment[0]), C.uint(value)) 201 if ret != OK { 202 return nil, fmt.Errorf("fail to compute Pedersen subtraction: " + getErrMsg(int64(ret))) 203 } 204 return resultSlice, nil 205 } 206 207 // PedersenSubCommitment Compute a commitment to x - y from commitments to x and y, without revealing the value x and y 208 // commitment1: commitment to x: Cx = xB + rB' 209 // commitment2: commitment to y: Cy = yB + sB' 210 // return: commitment to x - y: C = (x - y)B + (r - s)B' 211 func PedersenSubCommitment(commitment1, commitment2 []byte) ([]byte, error) { 212 if len(commitment1) != POINT_SIZE || len(commitment2) != POINT_SIZE { 213 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": commitment length should 32-byte") 214 } 215 var commitment [POINT_SIZE]byte 216 commitmentSlice := commitment[:] 217 ret := C.pedersen_point_sub(unsafe.Pointer(&commitmentSlice[0]), 218 unsafe.Pointer(&commitment1[0]), 219 unsafe.Pointer(&commitment2[0])) 220 if ret != OK { 221 return nil, fmt.Errorf("fail to compute Pedersen subtraction: " + getErrMsg(int64(ret))) 222 } 223 return commitmentSlice, nil 224 } 225 226 // PedersenSubOpening Compute opening1 - opening2. Openings are big numbers with 256 bits. 227 // opening1, opening2: two openings r and s 228 // return: the result opening r - s 229 func PedersenSubOpening(opening1, opening2 []byte) ([]byte, error) { 230 if len(opening1) != POINT_SIZE || len(opening2) != POINT_SIZE { 231 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": commitment or opening length should 32-byte") 232 } 233 var opening [POINT_SIZE]byte 234 openingSlice := opening[:] 235 ret := C.pedersen_scalar_sub(unsafe.Pointer(&openingSlice[0]), 236 unsafe.Pointer(&opening1[0]), 237 unsafe.Pointer(&opening2[0])) 238 if ret != OK { 239 return nil, fmt.Errorf("fail to compute opening subtraction: " + getErrMsg(int64(ret))) 240 } 241 return openingSlice, nil 242 } 243 244 // PedersenSubCommitmentWithOpening Compute a commitment to x - y without from two commitments of x and y respectively 245 // commitment1: commitment to x: Cx = xB + rB' 246 // commitment2: commitment to y: Cy = yB + sB' 247 // return1: the new commitment to x - y: C' = (x - y)B + (r - s)B' 248 // return2: the new opening r - s 249 func PedersenSubCommitmentWithOpening(commitment1, commitment2, opening1, opening2 []byte) ([]byte, []byte, error) { 250 commitment, err := PedersenSubCommitment(commitment1, commitment2) 251 if err != nil { 252 return nil, nil, err 253 } 254 opening, err := PedersenSubOpening(opening1, opening2) 255 if err != nil { 256 return nil, nil, err 257 } 258 return commitment, opening, nil 259 } 260 261 // PedersenMulNum Compute a commitment to x * y from a commitment to x and an integer y, without revealing the value x and y 262 // commitment1: commitment to x: Cx = xB + rB' 263 // value: integer value y 264 // return: commitment to x * y: C = (x * y)B + (r * y)B' 265 func PedersenMulNum(commitment1 []byte, value uint64) ([]byte, error) { 266 if len(commitment1) != POINT_SIZE { 267 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": commitment length should 32-byte") 268 } 269 var commitment [POINT_SIZE]byte 270 commitmentSlice := commitment[:] 271 ret := C.pedersen_commitment_mul_num(unsafe.Pointer(&commitmentSlice[0]), 272 unsafe.Pointer(&commitment1[0]), 273 C.uint(value)) 274 if ret != OK { 275 return nil, fmt.Errorf("fail to compute Pedersen multiplication: " + getErrMsg(int64(ret))) 276 } 277 return commitmentSlice, nil 278 } 279 280 // PedersenMulOpening Compute opening1 * integer. Openings are big numbers with 256 bits. 281 // opening1: the input opening r 282 // value: the input integer value y 283 // return: the multiplication r * y as a big number with 256 bits in []byte form 284 func PedersenMulOpening(opening1 []byte, value uint64) ([]byte, error) { 285 if len(opening1) != POINT_SIZE { 286 return nil, fmt.Errorf(ERR_MSG_INVALID_INPUT + ": opening length should 32-byte") 287 } 288 var opening [POINT_SIZE]byte 289 openingSlice := opening[:] 290 ret := C.pedersen_scalar_mul(unsafe.Pointer(&openingSlice[0]), 291 unsafe.Pointer(&opening1[0]), 292 C.uint(value)) 293 if ret != OK { 294 return nil, fmt.Errorf("fail to compute opening multiplication: " + getErrMsg(int64(ret))) 295 } 296 return openingSlice, nil 297 } 298 299 // PedersenMulNumWithOpening Compute a commitment to x * y from a commitment to x and an integer y, without revealing the value x and y 300 // commitment: commitment to x: Cx = xB + rB' 301 // opening: opening to Cx: r 302 // value: integer value y 303 // return1: commitment to x * y: C = (x * y)B + (r * y)B' 304 // return2: opening to the result commitment: r * y 305 func PedersenMulNumWithOpening(commitment []byte, opening []byte, value uint64) ([]byte, []byte, error) { 306 commitmentNew, err := PedersenMulNum(commitment, value) 307 if err != nil { 308 return nil, nil, err 309 } 310 openingNew, err := PedersenMulOpening(opening, value) 311 if err != nil { 312 return nil, nil, err 313 } 314 return commitmentNew, openingNew, nil 315 }