-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bab8ef6
commit 3c729c4
Showing
89 changed files
with
11,129 additions
and
144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
name: Dart | ||
|
||
on: | ||
workflow_call: | ||
workflow_dispatch: | ||
pull_request: | ||
branches: | ||
- main | ||
paths: | ||
- "dart/**" | ||
- "proto/**" | ||
- ".github/workflows/*dart*" | ||
- "devops/**" | ||
push: | ||
branches: | ||
- main | ||
paths: | ||
- "dart/**" | ||
- "proto/**" | ||
- ".github/workflows/*dart*" | ||
- "devops/**" | ||
|
||
jobs: | ||
build-and-test-dart: | ||
name: Test Dart code | ||
runs-on: ${{ matrix.os-artifact[0] }} | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
os-artifact: [ [ubuntu-latest, linux], [windows-latest, windows], [macos-latest, macos] ] | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Dart | ||
uses: dart-lang/setup-dart@v1 | ||
- name: Set up Python | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: 3.9 | ||
|
||
- name: Download workflow artifact | ||
uses: dawidd6/action-download-artifact@v2.17.0 | ||
with: | ||
workflow: "build-libs.yml" | ||
path: ./libs/${{ matrix.os-artifact[1] }} | ||
github_token: ${{ secrets.GITHUB_TOKEN }} | ||
name: ${{ matrix.os-artifact[1] }} | ||
|
||
- name: Install Dart dependencies | ||
run: dart pub get | ||
shell: pwsh | ||
working-directory: dart | ||
|
||
- name: Build, Test, Pack | ||
run: | | ||
python ../devops/build_sdks.py --language=python | ||
dart test ./lib/test/test-okapi.dart | ||
shell: pwsh | ||
working-directory: dart | ||
env: | ||
API_GITHUB_TOKEN: ${{ secrets.API_GITHUB_TOKEN }} | ||
LD_LIBRARY_PATH: "${{ github.workspace }}/libs" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Files and directories created by pub. | ||
.dart_tool/ | ||
.packages | ||
|
||
# Conventional directory for build output. | ||
build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## 1.0.0 | ||
|
||
- Initial version. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Dart bindings for okapi binary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# This file configures the static analysis results for your project (errors, | ||
# warnings, and lints). | ||
# | ||
# This enables the 'recommended' set of lints from `package:lints`. | ||
# This set helps identify many issues that may lead to problems when running | ||
# or consuming Dart code, and enforces writing Dart using a single, idiomatic | ||
# style and format. | ||
# | ||
# If you want a smaller set of lints you can change this to specify | ||
# 'package:lints/core.yaml'. These are just the most critical lints | ||
# (the recommended set includes the core lints). | ||
# The core lints are also what is used by pub.dev for scoring packages. | ||
|
||
include: package:lints/recommended.yaml | ||
|
||
# Uncomment the following section to specify additional rules. | ||
|
||
# linter: | ||
# rules: | ||
# - camel_case_types | ||
|
||
# analyzer: | ||
# exclude: | ||
# - path/to/excluded/files/** | ||
|
||
# For more information about the core and recommended set of lints, see | ||
# https://dart.dev/go/core-lints | ||
|
||
# For additional information about configuring this file, see | ||
# https://dart.dev/guides/language/analysis-options |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import 'dart:ffi'; | ||
|
||
import 'package:okapi_dart/okapi_native.dart'; | ||
import 'package:okapi_dart/proto/okapi/hashing/v1/hashing.pb.dart'; | ||
import 'package:okapi_dart/proto/okapi/keys/v1/keys.pb.dart'; | ||
import 'package:okapi_dart/proto/okapi/proofs/v1/proofs.pb.dart'; | ||
import 'package:okapi_dart/proto/okapi/security/v1/security.pb.dart'; | ||
import 'package:okapi_dart/proto/okapi/transport/v1/transport.pb.dart'; | ||
|
||
class DidComm { | ||
static final _didcommPack = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('didcomm_pack'); | ||
static final _didcommUnpack = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('didcomm_unpack'); | ||
static final _didcommSign = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('didcomm_sign'); | ||
static final _didcommVerify = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('didcomm_verify'); | ||
|
||
PackResponse pack(PackRequest request) => | ||
OkapiNative.nativeCall(_didcommPack, request, PackResponse()); | ||
|
||
UnpackResponse unpack(UnpackRequest request) => | ||
OkapiNative.nativeCall(_didcommUnpack, request, UnpackResponse()); | ||
|
||
SignResponse sign(SignRequest request) => | ||
OkapiNative.nativeCall(_didcommSign, request, SignResponse()); | ||
|
||
VerifyResponse verify(VerifyRequest request) => | ||
OkapiNative.nativeCall(_didcommVerify, request, VerifyResponse()); | ||
} | ||
|
||
class DidKey { | ||
static final _didkeyGenerate = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('didkey_generate'); | ||
static final _didkeyResolve = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('didkey_resolve'); | ||
|
||
static GenerateKeyResponse generate(GenerateKeyRequest request) => | ||
OkapiNative.nativeCall(_didkeyGenerate, request, GenerateKeyResponse()); | ||
|
||
static ResolveResponse resolve(ResolveRequest request) => | ||
OkapiNative.nativeCall(_didkeyResolve, request, ResolveResponse()); | ||
} | ||
|
||
class LdProofs { | ||
static final _ldproofsCreateProof = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>( | ||
'ldproofs_create_proof'); | ||
static final _ldproofsVerifyProof = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>( | ||
'ldproofs_verify_proof'); | ||
|
||
static CreateProofResponse createProof(CreateProofRequest request) => | ||
OkapiNative.nativeCall( | ||
_ldproofsCreateProof, request, CreateProofResponse()); | ||
|
||
static VerifyProofResponse verifyProof(VerifyProofRequest request) => | ||
OkapiNative.nativeCall( | ||
_ldproofsVerifyProof, request, VerifyProofResponse()); | ||
} | ||
|
||
class Oberon { | ||
static final _oberonCreateKey = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('oberon_create_key'); | ||
static final _oberonCreateProof = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>( | ||
'oberon_create_proof'); | ||
static final _oberonCreateToken = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>( | ||
'oberon_create_token'); | ||
static final _oberonBlindToken = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('oberon_blind_token'); | ||
static final _oberonUnBlindToken = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>( | ||
'oberon_unblind_token'); | ||
static final _oberonVerifyProof = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>( | ||
'oberon_verify_proof'); | ||
|
||
static CreateOberonKeyResponse CreateKey(CreateOberonKeyRequest request) => | ||
OkapiNative.nativeCall( | ||
_oberonCreateKey, request, CreateOberonKeyResponse()); | ||
|
||
static CreateOberonProofResponse CreateProof( | ||
CreateOberonProofRequest request) => | ||
OkapiNative.nativeCall( | ||
_oberonCreateProof, request, CreateOberonProofResponse()); | ||
static CreateOberonTokenResponse CreateToken( | ||
CreateOberonTokenRequest request) => | ||
OkapiNative.nativeCall( | ||
_oberonCreateToken, request, CreateOberonTokenResponse()); | ||
static BlindOberonTokenResponse BlindToken(BlindOberonTokenRequest request) => | ||
OkapiNative.nativeCall( | ||
_oberonBlindToken, request, BlindOberonTokenResponse()); | ||
static UnBlindOberonTokenResponse UnBlindToken( | ||
UnBlindOberonTokenRequest request) => | ||
OkapiNative.nativeCall( | ||
_oberonUnBlindToken, request, UnBlindOberonTokenResponse()); | ||
static VerifyOberonProofResponse VerifyProof( | ||
VerifyOberonProofRequest request) => | ||
OkapiNative.nativeCall( | ||
_oberonVerifyProof, request, VerifyOberonProofResponse()); | ||
} | ||
|
||
class Hashing { | ||
static final _blake3Hash = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('blake3_hash'); | ||
static final _blake3KeyedHash = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('blake3_keyed_hash'); | ||
static final _blake3DeriveKey = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('blake3_derive_key'); | ||
static final _sha256Hash = OkapiNative.library | ||
.lookupFunction<OkapiFunctionNative, OkapiFunction>('sha256_hash'); | ||
|
||
static Blake3HashResponse blake3Hash(Blake3HashRequest request) => | ||
OkapiNative.nativeCall(_blake3Hash, request, Blake3HashResponse()); | ||
static Blake3KeyedHashResponse blake3KeyedHash( | ||
Blake3KeyedHashRequest request) => | ||
OkapiNative.nativeCall( | ||
_blake3KeyedHash, request, Blake3KeyedHashResponse()); | ||
static Blake3DeriveKeyResponse blake3DeriveKey( | ||
Blake3DeriveKeyRequest request) => | ||
OkapiNative.nativeCall( | ||
_blake3DeriveKey, request, Blake3DeriveKeyResponse()); | ||
static SHA256HashResponse sha256Hash(SHA256HashRequest request) => | ||
OkapiNative.nativeCall(_sha256Hash, request, SHA256HashResponse()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import 'dart:ffi'; | ||
import 'dart:io' show Platform, Directory; | ||
import 'dart:typed_data'; | ||
|
||
import 'package:ffi/ffi.dart'; | ||
import 'package:path/path.dart' as path; | ||
import 'package:protobuf/protobuf.dart' as $pb; | ||
|
||
class OkapiByteBuffer extends Struct { | ||
@Int64() | ||
external int len; | ||
external Pointer<Int8> data; | ||
} | ||
|
||
typedef ErrorCode = Int32; | ||
|
||
class ExternError extends Struct { | ||
@ErrorCode() | ||
external int code; | ||
external Pointer<Utf8> message; | ||
} | ||
|
||
typedef OkapiFunctionNative = Int32 Function( | ||
OkapiByteBuffer, Pointer<OkapiByteBuffer>, Pointer<ExternError>); | ||
typedef OkapiFunction = int Function( | ||
OkapiByteBuffer, Pointer<OkapiByteBuffer>, Pointer<ExternError>); | ||
typedef OkapiFreeFunctionNative = Void Function(OkapiByteBuffer); | ||
typedef OkapiFreeFunction = void Function(OkapiByteBuffer); | ||
|
||
class OkapiNative { | ||
static final DynamicLibrary library = loadNativeLibrary(); | ||
static final okapiByteBufferFree = OkapiNative.library | ||
.lookupFunction<OkapiFreeFunctionNative, OkapiFreeFunction>( | ||
'okapi_bytebuffer_free'); | ||
static final okapiStringFree = OkapiNative.library | ||
.lookupFunction<OkapiFreeFunctionNative, OkapiFreeFunction>( | ||
'okapi_string_free'); | ||
|
||
static T nativeCall<T extends $pb.GeneratedMessage>( | ||
Function nativeFunction, $pb.GeneratedMessage request, T response) { | ||
final requestBufferPtr = createRequestBuffer(request); | ||
final responseBufferPtr = | ||
calloc<OkapiByteBuffer>(sizeOf<OkapiByteBuffer>()); | ||
final err = calloc<ExternError>(sizeOf<ExternError>()); | ||
nativeFunction(requestBufferPtr.ref, responseBufferPtr, err); | ||
final errCode = err.ref.code; | ||
if (errCode != 0) { | ||
final errString = err.ref.message.toDartString(); | ||
throw Exception("Okapi native error code=$errCode, message=$errString"); | ||
} | ||
|
||
response.mergeFromBuffer( | ||
responseBufferPtr.ref.data.asTypedList(responseBufferPtr.ref.len)); | ||
// Free native and managed memory | ||
freeNativeMemory(requestBufferPtr, okapiByteBufferFree, responseBufferPtr); | ||
return response; | ||
} | ||
|
||
static DynamicLibrary loadNativeLibrary() { | ||
// Support LD_LIBRARY_PATH | ||
String libraryPath = Platform.environment["LD_LIBRARY_PATH"] ?? | ||
path.join(Directory.current.path, '..', 'libs'); | ||
String libraryName = ""; | ||
if (Platform.isWindows) { | ||
libraryName = path.join("windows", "okapi.dll"); | ||
} else if (Platform.isLinux) { | ||
libraryName = path.join("linux", "libokapi.so"); | ||
} else if (Platform.isMacOS) { | ||
libraryName = path.join("macos", "libokapi.dylib"); | ||
} | ||
// TODO - Support Android, and maybe iOS? | ||
libraryPath = path.join(libraryPath, libraryName); | ||
final nativeLib = DynamicLibrary.open(libraryPath); | ||
return nativeLib; | ||
} | ||
|
||
static Pointer<Int8> byteDataToPointer(ByteBuffer byteBuffer) { | ||
final uint8List = byteBuffer.asInt8List(); | ||
final length = byteBuffer.lengthInBytes; | ||
final result = calloc<Int8>(length); | ||
|
||
for (var i = 0; i < length; ++i) { | ||
result[i] = uint8List[i]; | ||
} | ||
|
||
return result; | ||
} | ||
|
||
static void freeNativeMemory( | ||
Pointer<OkapiByteBuffer> requestBuffer, | ||
OkapiFreeFunction okapiByteBufferFree, | ||
Pointer<OkapiByteBuffer> responseBuffer) { | ||
calloc.free(requestBuffer.ref.data); | ||
calloc.free(requestBuffer); | ||
okapiByteBufferFree(responseBuffer.ref); | ||
} | ||
|
||
static Pointer<OkapiByteBuffer> createRequestBuffer( | ||
$pb.GeneratedMessage request) { | ||
final Pointer<OkapiByteBuffer> requestBuffer = calloc<OkapiByteBuffer>(); | ||
final buffer = request.writeToBuffer().buffer; | ||
requestBuffer.ref.len = buffer.lengthInBytes; | ||
requestBuffer.ref.data = byteDataToPointer(buffer); | ||
return requestBuffer; | ||
} | ||
} |
Oops, something went wrong.