Skip to content

Commit 1a53a23

Browse files
Swift Oberon support (#224)
1 parent cb80d4a commit 1a53a23

File tree

3 files changed

+158
-2
lines changed

3 files changed

+158
-2
lines changed

python/tests/test_oberon.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def test_oberon_demo(self):
1717

1818
self.assertTrue(result.valid, "Proof should verify")
1919

20-
def test_demo_with_binding(self):
20+
def test_demo_with_blinding(self):
2121
key = Oberon.create_key(CreateOberonKeyRequest())
2222
data = bytes("alice", "utf8")
2323
nonce = bytes("1234", "utf8")
@@ -58,4 +58,4 @@ def test_demo_with_binding(self):
5858
proof = Oberon.create_proof(proof_request)
5959
# Verifies tries to verify proof, fails
6060
result = Oberon.verify_proof(VerifyOberonProofRequest(data=data, nonce=nonce, pk=key.pk, proof=proof.proof))
61-
self.assertFalse(result.valid)
61+
self.assertFalse(result.valid)

swift/Okapi/Sources/OkapiSwift/Okapi.swift

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,53 @@ public struct DidComm {
6969
return response;
7070
}
7171
}
72+
73+
public struct Oberon {
74+
public static func createKey(request: Okapi_Security_V1_CreateOberonKeyRequest) throws -> Okapi_Security_V1_CreateOberonKeyResponse {
75+
let response: Okapi_Security_V1_CreateOberonKeyResponse = try OkapiNative.nativeCall(request: request,
76+
nativeFunction: { (requestBuffer, responseBufferPtr, errorBufferPtr) in
77+
oberon_create_key(requestBuffer, responseBufferPtr, errorBufferPtr)
78+
});
79+
return response;
80+
}
81+
82+
public static func createProof(request: Okapi_Security_V1_CreateOberonProofRequest) throws -> Okapi_Security_V1_CreateOberonProofResponse {
83+
let response: Okapi_Security_V1_CreateOberonProofResponse = try OkapiNative.nativeCall(request: request,
84+
nativeFunction: { (requestBuffer, responseBufferPtr, errorBufferPtr) in
85+
oberon_create_proof(requestBuffer, responseBufferPtr, errorBufferPtr)
86+
});
87+
return response;
88+
}
89+
90+
public static func createToken(request: Okapi_Security_V1_CreateOberonTokenRequest) throws -> Okapi_Security_V1_CreateOberonTokenResponse {
91+
let response: Okapi_Security_V1_CreateOberonTokenResponse = try OkapiNative.nativeCall(request: request,
92+
nativeFunction: { (requestBuffer, responseBufferPtr, errorBufferPtr) in
93+
oberon_create_token(requestBuffer, responseBufferPtr, errorBufferPtr)
94+
});
95+
return response;
96+
}
97+
98+
public static func blindToken(request: Okapi_Security_V1_BlindOberonTokenRequest) throws -> Okapi_Security_V1_BlindOberonTokenResponse {
99+
let response: Okapi_Security_V1_BlindOberonTokenResponse = try OkapiNative.nativeCall(request: request,
100+
nativeFunction: { (requestBuffer, responseBufferPtr, errorBufferPtr) in
101+
oberon_blind_token(requestBuffer, responseBufferPtr, errorBufferPtr)
102+
});
103+
return response;
104+
}
105+
106+
public static func unblindToken(request: Okapi_Security_V1_UnBlindOberonTokenRequest) throws -> Okapi_Security_V1_UnBlindOberonTokenResponse {
107+
let response: Okapi_Security_V1_UnBlindOberonTokenResponse = try OkapiNative.nativeCall(request: request,
108+
nativeFunction: { (requestBuffer, responseBufferPtr, errorBufferPtr) in
109+
oberon_unblind_token(requestBuffer, responseBufferPtr, errorBufferPtr)
110+
});
111+
return response;
112+
}
113+
114+
public static func verifyProof(request: Okapi_Security_V1_VerifyOberonProofRequest) throws -> Okapi_Security_V1_VerifyOberonProofResponse {
115+
let response: Okapi_Security_V1_VerifyOberonProofResponse = try OkapiNative.nativeCall(request: request,
116+
nativeFunction: { (requestBuffer, responseBufferPtr, errorBufferPtr) in
117+
oberon_verify_proof(requestBuffer, responseBufferPtr, errorBufferPtr)
118+
});
119+
return response;
120+
}
121+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
//
2+
// Created by Scott Phillips on 9/8/21.
3+
//
4+
5+
import XCTest
6+
import SwiftProtobuf
7+
import Foundation
8+
9+
@testable import OkapiSwift
10+
11+
final class OberonTests: XCTestCase {
12+
func testOberonDemo() throws {
13+
let key = try Oberon.createKey(request: Okapi_Security_V1_CreateOberonKeyRequest())
14+
let data = "alice".data(using: .utf8) ?? Data()
15+
let nonce = "1234".data(using: .utf8) ?? Data()
16+
var createTokenRequest = Okapi_Security_V1_CreateOberonTokenRequest()
17+
createTokenRequest.data = data
18+
createTokenRequest.sk = key.sk
19+
let token = try Oberon.createToken(request: createTokenRequest)
20+
var createProofRequest = Okapi_Security_V1_CreateOberonProofRequest()
21+
createProofRequest.data = data
22+
createProofRequest.nonce = nonce
23+
createProofRequest.token = token.token
24+
let proof = try Oberon.createProof(request: createProofRequest)
25+
var verifyProofRequest = Okapi_Security_V1_VerifyOberonProofRequest()
26+
verifyProofRequest.data = data
27+
verifyProofRequest.nonce = nonce
28+
verifyProofRequest.pk = key.pk
29+
verifyProofRequest.proof = proof.proof
30+
let result = try Oberon.verifyProof(request: verifyProofRequest)
31+
32+
XCTAssertTrue(result.valid, "Proof should verify")
33+
}
34+
35+
func testDemoWithBlinding() throws {
36+
let key = try Oberon.createKey(request: Okapi_Security_V1_CreateOberonKeyRequest())
37+
let data = "alice".data(using: .utf8) ?? Data()
38+
let nonce = "1234".data(using: .utf8) ?? Data()
39+
40+
let issuer_2fa = "issuer code".data(using: .utf8) ?? Data()
41+
var tokenRequest = Okapi_Security_V1_CreateOberonTokenRequest()
42+
tokenRequest.data = data
43+
tokenRequest.sk = key.sk
44+
tokenRequest.blinding.append(issuer_2fa)
45+
let blindedToken = try Oberon.createToken(request: tokenRequest)
46+
47+
// Holder unblinds the token
48+
var unblindRequest = Okapi_Security_V1_UnBlindOberonTokenRequest()
49+
unblindRequest.token = blindedToken.token
50+
unblindRequest.blinding.append(issuer_2fa)
51+
let token = try Oberon.unblindToken(request: unblindRequest)
52+
53+
// Holder prepares a proof without blinding
54+
var createProofRequest = Okapi_Security_V1_CreateOberonProofRequest()
55+
createProofRequest.data = data
56+
createProofRequest.nonce = nonce
57+
createProofRequest.token = token.token
58+
var proof = try Oberon.createProof(request: createProofRequest)
59+
// Verifier verifies the proof
60+
var verifyProofRequest = Okapi_Security_V1_VerifyOberonProofRequest()
61+
verifyProofRequest.data = data
62+
verifyProofRequest.nonce = nonce
63+
verifyProofRequest.pk = key.pk
64+
verifyProofRequest.proof = proof.proof
65+
var result = try Oberon.verifyProof(request: verifyProofRequest)
66+
XCTAssertTrue(result.valid)
67+
68+
// Holder blinds the token with a personal pin
69+
let userPin = "0042".data(using: .utf8) ?? Data()
70+
var blindRequest = Okapi_Security_V1_BlindOberonTokenRequest()
71+
blindRequest.token = token.token
72+
blindRequest.blinding.append(userPin)
73+
74+
var userBlindedToken = try Oberon.blindToken(request: blindRequest)
75+
var proofRequest = Okapi_Security_V1_CreateOberonProofRequest()
76+
proofRequest.data = data
77+
proofRequest.nonce = nonce
78+
proofRequest.token = userBlindedToken.token
79+
// Verifier verifies the proof
80+
verifyProofRequest = Okapi_Security_V1_VerifyOberonProofRequest()
81+
verifyProofRequest.data = data
82+
verifyProofRequest.nonce = nonce
83+
verifyProofRequest.pk = key.pk
84+
verifyProofRequest.proof = proof.proof
85+
result = try Oberon.verifyProof(request: verifyProofRequest)
86+
XCTAssertTrue(result.valid)
87+
88+
// Bad actor creates a proof with incorrect blinding pin
89+
let badPin = "invalid pin".data(using: .utf8) ?? Data()
90+
proofRequest = Okapi_Security_V1_CreateOberonProofRequest()
91+
proofRequest.data = data
92+
proofRequest.nonce = nonce
93+
proofRequest.token = userBlindedToken.token
94+
proofRequest.blinding.append(badPin)
95+
96+
proof = try Oberon.createProof(request: proofRequest)
97+
// Verify tries to verify proof, fails
98+
verifyProofRequest = Okapi_Security_V1_VerifyOberonProofRequest()
99+
verifyProofRequest.data = data
100+
verifyProofRequest.nonce = nonce
101+
verifyProofRequest.pk = key.pk
102+
verifyProofRequest.proof = proof.proof
103+
result = try Oberon.verifyProof(request: verifyProofRequest)
104+
XCTAssertFalse(result.valid, "Bad actor cannot verify")
105+
}
106+
}

0 commit comments

Comments
 (0)