Skip to content

Commit e23c3c0

Browse files
committed
Initial API for Confidential Transactions
1 parent 5e71ec3 commit e23c3c0

File tree

4 files changed

+265
-32
lines changed

4 files changed

+265
-32
lines changed

Sources/zkp/Surjection.swift

+208
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
//
2+
// Surjection.swift
3+
// GigaBitcoin/secp256k1.swift
4+
//
5+
// Copyright (c) 2023 GigaBitcoin LLC
6+
// Distributed under the MIT software license
7+
//
8+
// See the accompanying file LICENSE for information
9+
//
10+
11+
import Foundation
12+
import zkp_bindings
13+
14+
// MARK: - secp256k1 + SurjectionProof
15+
16+
public extension secp256k1 {
17+
enum Surjection {
18+
struct Proof {
19+
let length = Int(32 * (1 + SECP256K1_SURJECTIONPROOF_MAX_USED_INPUTS))
20+
/// Total number of input asset tags
21+
public let nInputs: Int
22+
/// Bitmap of which input tags are used in the surjection proof
23+
public let usedInputs: Data
24+
/// Borromean signature: e0, scalars
25+
public let rawRepresentation: Data
26+
/// The index of the actual input that is secretly mapped to the output
27+
public let inputIndex: Int
28+
/// The ephemeral asset tag of the output
29+
public let ephemeralOutputTag: Data
30+
/// the blinding key of the output
31+
public let blindingKey: [UInt8]
32+
33+
/// Surjection proof initialization and generation functions
34+
@usableFromInline init(
35+
fixedInputTags: [secp256k1_fixed_asset_tag],
36+
ephemeralInputTags: [secp256k1_generator],
37+
inputBlindingKey: [UInt8]
38+
) throws {
39+
var outSurjectionProof = secp256k1_surjectionproof()
40+
var ephemeralOutputTag = secp256k1_generator()
41+
var outputBlindingKey = [UInt8](repeating: 0, count: 64)
42+
var outInputIndex = 0
43+
var fixedOutputTag = secp256k1_fixed_asset_tag()
44+
var randomSeed: Int8 = 3
45+
var proofData = [UInt8](repeating: 0, count: length)
46+
47+
guard secp256k1_surjectionproof_initialize(
48+
secp256k1.Context.raw,
49+
&outSurjectionProof,
50+
&outInputIndex,
51+
fixedInputTags,
52+
fixedInputTags.count,
53+
fixedInputTags.count,
54+
&fixedOutputTag,
55+
100,
56+
&randomSeed
57+
).boolValue,
58+
secp256k1_surjectionproof_generate(
59+
secp256k1.Context.raw,
60+
&outSurjectionProof,
61+
ephemeralInputTags,
62+
ephemeralInputTags.count,
63+
&ephemeralOutputTag,
64+
outInputIndex,
65+
inputBlindingKey,
66+
&outputBlindingKey
67+
).boolValue else {
68+
throw secp256k1Error.underlyingCryptoError
69+
}
70+
71+
secp256k1_swift_surjection_proof_parse(&proofData, outSurjectionProof)
72+
73+
self.blindingKey = outputBlindingKey
74+
self.nInputs = outSurjectionProof.n_inputs
75+
self.inputIndex = outInputIndex
76+
self.usedInputs = Data(outSurjectionProof.used_inputs)
77+
self.rawRepresentation = Data(proofData)
78+
self.ephemeralOutputTag = Data(ephemeralOutputTag.data)
79+
}
80+
81+
static func verify(
82+
proof: inout secp256k1_surjectionproof,
83+
ephemeralInputTags: [secp256k1_generator],
84+
ephemeralOutputTag: inout secp256k1_generator
85+
) -> Bool {
86+
secp256k1_surjectionproof_verify(
87+
secp256k1.Context.raw,
88+
&proof,
89+
ephemeralInputTags,
90+
ephemeralInputTags.count,
91+
&ephemeralOutputTag
92+
).boolValue
93+
}
94+
}
95+
}
96+
}
97+
98+
internal extension Data {
99+
init(_ usedInputs: UsedInputsType) {
100+
self = Data(Swift.withUnsafeBytes(of: usedInputs) { [UInt8]($0) })
101+
}
102+
103+
init(_ ephemeralTag: EphemeralTagType) {
104+
self = Data(Swift.withUnsafeBytes(of: ephemeralTag) { [UInt8]($0) })
105+
}
106+
}
107+
108+
typealias UsedInputsType = (
109+
UInt8,
110+
UInt8,
111+
UInt8,
112+
UInt8,
113+
UInt8,
114+
UInt8,
115+
UInt8,
116+
UInt8,
117+
UInt8,
118+
UInt8,
119+
UInt8,
120+
UInt8,
121+
UInt8,
122+
UInt8,
123+
UInt8,
124+
UInt8,
125+
UInt8,
126+
UInt8,
127+
UInt8,
128+
UInt8,
129+
UInt8,
130+
UInt8,
131+
UInt8,
132+
UInt8,
133+
UInt8,
134+
UInt8,
135+
UInt8,
136+
UInt8,
137+
UInt8,
138+
UInt8,
139+
UInt8,
140+
UInt8
141+
)
142+
143+
typealias EphemeralTagType = (
144+
UInt8,
145+
UInt8,
146+
UInt8,
147+
UInt8,
148+
UInt8,
149+
UInt8,
150+
UInt8,
151+
UInt8,
152+
UInt8,
153+
UInt8,
154+
UInt8,
155+
UInt8,
156+
UInt8,
157+
UInt8,
158+
UInt8,
159+
UInt8,
160+
UInt8,
161+
UInt8,
162+
UInt8,
163+
UInt8,
164+
UInt8,
165+
UInt8,
166+
UInt8,
167+
UInt8,
168+
UInt8,
169+
UInt8,
170+
UInt8,
171+
UInt8,
172+
UInt8,
173+
UInt8,
174+
UInt8,
175+
UInt8,
176+
UInt8,
177+
UInt8,
178+
UInt8,
179+
UInt8,
180+
UInt8,
181+
UInt8,
182+
UInt8,
183+
UInt8,
184+
UInt8,
185+
UInt8,
186+
UInt8,
187+
UInt8,
188+
UInt8,
189+
UInt8,
190+
UInt8,
191+
UInt8,
192+
UInt8,
193+
UInt8,
194+
UInt8,
195+
UInt8,
196+
UInt8,
197+
UInt8,
198+
UInt8,
199+
UInt8,
200+
UInt8,
201+
UInt8,
202+
UInt8,
203+
UInt8,
204+
UInt8,
205+
UInt8,
206+
UInt8,
207+
UInt8
208+
)

Sources/zkp_bindings/include/Utility.h Sources/zkp_bindings/include/secp256k1_swift.h

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Utility.h
2+
// secp256k1_swift.h
33
// GigaBitcoin/secp256k1.swift
44
//
55
// Copyright (c) 2021 GigaBitcoin LLC
@@ -9,6 +9,7 @@
99
//
1010

1111
#include "./secp256k1.h"
12+
#include "./secp256k1_surjectionproof.h"
1213

1314
/// Exposes secp256k1 memczero implementation to the bindings target
1415
/// @param s pointer to an array to be zero'd by the function
@@ -21,3 +22,13 @@ void secp256k1_swift_memczero(void *s, size_t len, int flag);
2122
/// @param input a pointer to the data to be hashed
2223
/// @param len the length of the data to be hashed
2324
void secp256k1_swift_sha256(unsigned char *output, const unsigned char *input, size_t len);
25+
26+
/// Parse a surjection proof
27+
/// @param data Borromean signature: e0, scalars
28+
/// @param proof data structure that holds a parsed surjection proof
29+
void secp256k1_swift_surjection_proof_parse(const unsigned char *data, secp256k1_surjectionproof proof);
30+
31+
/// Serialize a surjection proof
32+
/// @param proof data structure that holds a parsed surjection proof
33+
/// @param data Borromean signature: e0, scalars
34+
void secp256k1_swift_surjection_proof_serialize(secp256k1_surjectionproof proof, const unsigned char *data);

Sources/zkp_bindings/src/Utility.c

-31
This file was deleted.
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//
2+
// secp256k1_swift.c
3+
// GigaBitcoin/secp256k1.swift
4+
//
5+
// Copyright (c) 2021 GigaBitcoin LLC
6+
// Distributed under the MIT software license
7+
//
8+
// See the accompanying file LICENSE for information
9+
//
10+
11+
#include "../include/secp256k1_swift.h"
12+
#include "../src/hash_impl.h"
13+
14+
/// Exposes secp256k1 memczero implementation to the bindings target
15+
/// @param s pointer to an array to be zero'd by the function
16+
/// @param len the length of the data to be zero'd
17+
/// @param flag zero memory if flag == 1. Flag must be 0 or 1. Constant time.
18+
void secp256k1_swift_memczero(void *s, size_t len, int flag) {
19+
secp256k1_memczero(s, len, flag);
20+
}
21+
22+
/// Exposes secp256k1 SHA256 implementation to the bindings target
23+
/// @param output pointer to an array to be filled by the function
24+
/// @param input a pointer to the data to be hashed
25+
/// @param len the length of the data to be hashed
26+
void secp256k1_swift_sha256(unsigned char *output, const unsigned char *input, size_t len) {
27+
secp256k1_sha256 hasher;
28+
secp256k1_sha256_initialize(&hasher);
29+
secp256k1_sha256_write(&hasher, input, len);
30+
secp256k1_sha256_finalize(&hasher, output);
31+
}
32+
33+
/// Parse a surjection proof
34+
/// @param data Borromean signature: e0, scalars
35+
/// @param proof data structure that holds a parsed surjection proof
36+
void secp256k1_swift_surjection_proof_parse(const unsigned char *data, secp256k1_surjectionproof proof) {
37+
data = proof.data;
38+
}
39+
40+
/// Serialize a surjection proof
41+
/// @param proof data structure that holds a parsed surjection proof
42+
/// @param data Borromean signature: e0, scalars
43+
void secp256k1_swift_surjection_proof_serialize(secp256k1_surjectionproof proof, const unsigned char *data) {
44+
memcpy(proof.data, &data, sizeof data);
45+
}

0 commit comments

Comments
 (0)