-
Notifications
You must be signed in to change notification settings - Fork 0
/
pedersenCommitments.c
139 lines (108 loc) · 3.19 KB
/
pedersenCommitments.c
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//
// pedersenCommitments.c
// testSM2
//
// Created by zuoyongyong on 2019/12/3.
// Copyright © 2019年 zuoyongyong. All rights reserved.
//
/// compute c = mG + rH
/// where m is the commited value, G is the group generator,
/// H is a random point and r is a blinding value.
///
#include <stdlib.h>
#include <string.h>
#include "pedersenCommitments.h"
#include "rand.h"
#include "bn.h"
#include "bnEx.h"
#include "ec_operations.h"
#include "bn_operations.h"
#include "sm2.h"
#include "sm3.h"
typedef struct PedersenCommSt
{
unsigned char comm[64];
unsigned char blind[32];
}pedersenComm;
/// compute c = mG + rH
/// where m is the to be blind factor , r is amount value ,G is the group generator,
/// H is a random point
///
//With this tool in hand we can go and replace the normal 8-byte integer
//amounts in Bitcoin transactions with 33-byte Pedersen commitments.
// CT reference address is https://people.xiph.org/~greg/confidential_values.txt
void genPedersenCommit(unsigned char *message, unsigned int messagelen, pedersenComm *commit)
{
if(message == NULL || commit == NULL)
{
return ;
}
BIGNUM *N;
BIGNUM *m;
BIGNUM *r;
BIGNUM *h;
BIGNUM *x;
BIGNUM *y;
BN_CTX *ctx;
EC_SM2_POINT *Pt,*Ph;
N = BN_new();
m = BN_new();
r = BN_new();
h = BN_new();
x = BN_new();
y = BN_new();
ctx= BN_CTX_new();
Pt = EC_SM2_POINT_new();
Ph = EC_SM2_POINT_new();
EC_SM2_GROUP_get_order(group, N);
// 1、gen 256bit random r
unsigned char blindFactor[32] = {0};
GenerateRandomBytes(blindFactor, 32);
BN_bin2bn(blindFactor, 32, r);
// 2、convert message to m
unsigned char hash[32] = {0};
SM3(message, messagelen, hash);
BN_bin2bn(hash, sizeof(hash), m);
// 3、caculate mG + rH
unsigned char temp[32] = {0};
rng(256, temp);
BN_bin2bn(temp, 32, h);
BN_nnmod(h, h, N, ctx);
EC_SM2_POINT_mul(group, Ph, h, G);
memset(temp,0,sizeof(temp));
// c = mG + rH
EC_SM2_POINT_mul(group, Pt, r, Ph);
EC_SM2_POINT_mul(group, Ph, m, G);
EC_SM2_POINT_add(group, Pt, Pt, Ph);
EC_SM2_POINT_affine2gem(group, Pt, Pt);
EC_SM2_POINT_get_point(Pt, x, y, h);
unsigned char szData[64] = {0};
BN_lshift(x, x, 256);
BN_add(x, x, y);
BN_bn2bin(x, szData);
//output pedersen commit and blind facctor
memcpy(commit->comm, szData, 64);
memcpy(commit->blind, blindFactor, 32);
BN_free(N);
BN_free(m);
BN_free(r);
BN_free(h);
BN_free(x);
BN_free(y);
BN_CTX_free(ctx);
EC_SM2_POINT_free(Pt);
EC_SM2_POINT_free(Ph);
}
extern void print_hex(uint8_t *label, uint8_t *data, uint16_t data_len);
void test_pedersenCommit()
{
unsigned char *message = "the message to pedersen commit";
unsigned int len = strlen(message);
pedersenComm com;
sm2_init();
// gen pedersen commit
genPedersenCommit(message, len, &com);
print_hex((uint8_t *)"pedersen commit is ", com.comm, sizeof(com.comm));
print_hex((uint8_t *)"pedersen commit blind is ", com.blind, sizeof(com.blind));
return ;
}