CryptoNets WebAssembly SDK
Powered by Private Identity®
https://private.id
CryptoNets™ Wasm Module Implementation is an npm package that uses the W3C WebAssembly to perform 1:N fully homomorphically encrypted (FHE) face recognition.
BENEFITS
- Face biometric capture
- Encrypted face recognition every 200ms
- 1:n biometric match in 60ms constant time
- Human age estimation
- Unlimited users (unlimited gallery size)
- Fair, accurate and unbiased
- Preserves user privacy with neural network cryptography + fully homomorphic encryption (CryptoNets)
- IEEE 2410 Standard for Biometric Privacy, ISO 27001, ISO 9001 compliant
- Exempt from GDPR, CCPA, BIPA, and HIPAA privacy law obligations
- Predicts in 50ms with or without network using local storage
BUILD
- Verified Identity
- Web Sign-in
- Payments
- Phone Unlock
- Ticketless Access Control
- Account Recovery
- Face CAPTCHA
Prerequisite
Sign up on the waitlist on https://private.id to obtain your apiKey.
Installation
npm install @privateid/cryptonets-web-sdk
Copy the necessary dependencies to the public folder of your app
"prestart": "cp -R ./node_modules/@privateid/cryptonets-web-sdk/wasm public/&& cp -R ./node_modules/@privateid/cryptonets-web-sdk/workers public/",
"prebuild": "cp -R ./node_modules/@privateid/cryptonets-web-sdk/wasm public/ && cp -R ./node_modules/@privateid/cryptonets-web-sdk/workers public/"
Add the necessary environment variables on the .env file in the root of your project
SKIP_PREFLIGHT_CHECK=true
REACT_APP_API_URL=
REACT_APP_API_KEY=
REACT_APP_WASM_MODULE= face_mask | face | voice
Optional environment variable
REACT_APP_API_ORCHESTRATION=
REACT_APP_SET_CACHE= true | false (Used for predict caching)
Load the WASM Module
The first step is to load and initialize the wasm module and clear the content of the local database.
import { loadPrivIdModule, clearDB } from '@privateid/cryptonets-web-sdk';
const isSupported = await loadPrivIdModule();
clearDB();
In case of .env file (evironment variable) does not work for you we have added a support to set the variables on load.
import { loadPrivIdModule } from '@privateid/cryptonets-web-sdk';
const isSupported =await loadPrivIdModule(
api_url,
api_key,
api_orchestration_url,
wasm_url,
wasm_module,
);
Status | Description |
---|---|
api_url | Equivalent to env variable REACT_APP_API_URL |
api_key | Equivalent to env variable REACT_APP_API_KEY |
api_orchestration_url | Equivalent to env variable REACT_APP_API_ORCHESTRATION_URL |
wasm_url | Please set it the same with api_url or REACT_APP_API_URL |
wasm_module | face_mask , face , voice |
The loadPrivIdModule() function returns an object to check if the device is supporting WASM and WebRTC.
{
support: boolean,
message: string,
}
Open or switch camera or close camera
The first step is to load and initialize the wasm module.
Open the camera
To open user camera use the openCamera function with element id of the video tag in the DOM
import { openCamera } from '@privateid/cryptonets-web-sdk';
const { devices, faceMode } = await openCamera(element);
it returns list of the available video devices.
Switch to another camera
To switch to another media device use the switchCamera function with the ID of the device to be used
import { switchCamera } from '@privateid/cryptonets-web-sdk';
switchCamera(deviceID);
for the mobile phone we can select whether it's front or back camera for this we pass 'front' or 'back' to the switch function
import { switchCamera } from '@privateid/cryptonets-web-sdk';
switchCamera('front');
Close the camera
To close user camera use the closeCamera function with element id of the video tag in the DOM.
import { closeCamera } from '@privateid/cryptonets-web-sdk';
closeCamera(element); // Will specifically look for the element id and will close that camera
closeCamera(); // By default will close opened camera using openCamera
isValid
Live demo: [https://age.devel.private.id]
isValid only exercises the is_valid()
call and does not find identity. The function detects if there is a valid face in the camera view or in an ImageData Array.
isValid accepts two parameters.
- callback: callback function to perform actions.
- ImageData: array of an image data to perform the face captcha on (optional)
import { isValid } from '@privateid/cryptonets-web-sdk';
const {imageData} = isValid(callback, imageData);
Returned data sample in callback function:
{
"status": "WASM_RESPONSE",
"returnValue": {
"error": 0,
"faces": [
{
"status": 0,
"box": {
"conf_score": 0.9809297323226929,
"top_left": {
"x": 843.5,
"y": 723.5
},
"bottom_right": {
"x": 1244.5,
"y": 1124.5
},
"eye_left": {
"x": 968.5,
"y": 788.5
},
"eye_right": {
"x": 1146,
"y": 790.5
}
}
}
]
}
}
Face CAPTCHA returns 17 possible coded results, as follows.
Property | Description |
---|---|
-1 | No Face |
0 | Valid Biometric |
1 | Image Spoof |
2 | Video Spoof |
3 | Too close |
4 | Too far away |
5 | Too far to right |
6 | Too far to left |
7 | Too far up |
8 | Too far down |
9 | Too blurry |
10 | Glasses on |
11 | Mask on |
12 | Chin too far left |
13 | Chin too far right |
14 | Chin too far up |
15 | Chin too far down |
Predict Age
Perform an age estimation using predictAge
function on all detected faces from image or camera.
import { predictAge } from '@privateid/cryptonets-web-sdk';
await predictAge(null, predictAgeCallback);
The function takes 3 parameters
Property | Description |
---|---|
imageData | If this parameter is provided it will check age of the imageData instead of opened camera. |
callback | The callback function to handle predictAge results. |
Callback
Here are sample returned data to callback from predictAge :
{
"status": "WASM_RESPONSE",
"returnValue": {
"error": 0,
"faces": [
{
"status": 0,
"age": 16.912670135498047,
"box": {
"top_left": {
"x": 486,
"y": 371
},
"bottom_right": {
"x": 652,
"y": 545
}
}
},
]
}
}
Enroll or predict
Perform a new enrollment (register a new user) or predict (authenticate a user) using the enroll1FA
or predict1FA
function
import { enroll1FA, predict1FA } from '@privateid/cryptonets-web-sdk';
enroll1FA(callback, {input_image_format: "rgba"}, returnPortrait?)
predict1FA(callback, {input_image_format: "rgba"})
The function takes 3 parameters
Property | Description |
---|---|
callback | The callback to be executed on each status |
config | The image format to be used for processing. Recommended: { input_image_format: "rgba" } |
returnPortrait | This flag is default true. If false portrait will not be returned in callback on a valid enroll call. |
Callback
The enroll1FA
and predict1FA
function provides 5 status updates to allow the developer to take action at different steps of the identification process.
Status | Description |
---|---|
VALID_FACE | A face is detected |
INVALID_FACE | A valid face is not detected |
ENROLLING | Enrollment (registration) starts of a valid face |
PREDICTING | Prediction (authentication) starts of a valid face |
WASM_RESPONSE | The prediction or enrollment process is complete |
Enroll Callback Sample Return:
{
"PI": {
"enroll_level": 1,
"factor": "face",
"guid": "06494353s2qr983sq043",
"uuid": "8452q1oqp864345q2p56"
},
"message": "Ok",
"status": 0,
"validation_status": [
{
"status": 0,
"conf_score": 0.8376305103302002
},
],
"token": "096AF75224F172BB81521D7F1B66E79C7925FB52172470E92C66479D510F83206425B8757F953D4A3766D18ADF080AA63B551AA9D71657A4FCE87AEE0EA5B82DB83EABC6DFF38B4010B26C2789C56EF2EC30303030303138356430346238666330"
}
Enroll also returns portrait (base64 image) in callback. (portrait converted to imageData can be used for face compare)
Predict Sample Return:
{
"message": "OK",
"status": 0,
"token": "09205CFA6AE80E55BEBB4BD96229F99E486B62D6DF8C6212736043E9A705CFBB4FF7A6BD05DDF43664D4053F70B64F24126DBC3DA50834F6126F7CC2E0268F34E7E378B8BCC3A94769F82683AB0E5BAF8F30303030303138356430346339373461",
"PI": {
"factor": "face",
"guid": "06494353s2qr983sq043",
"uuid": "8452q1oqp864345q2p56",
"probability": 1,
"enroll_level": 1
},
"PI_list": [
{
"factor": "face",
"guid": "06494353s2qr983sq043",
"uuid": "8452q1oqp864345q2p56",
"probability": 1,
"enroll_level": 1
}
],
"validation_status": [
{
"status": 0,
"conf_score": 0.609839916229248
}
]
}
Continuous Authentication
Live demo: https://usc.priv.id
Perform continuous user prediction (authentication) using the continuousAuthentication
function. This provides the same status updates as Predict.
import { continuousAuthentication } from '@privateid/cryptonets-web-sdk';
continuousAuthentication(callback, configuration, element)
The continuousAuthentication function takes 4 parameters
Property | Description |
---|---|
callback | The callback to be executed on each status |
configuration | Please use recommended: { input_image_format: "rgba" } |
element | (Optional) Element ID of the video tag where the camera is open. |
isValidPhotoID
This function finds, crops, align and validate, front and back of the photoID, and returns back a valid cropped and aligned image of the photoID
import { isValidPhotoID } from '@privateid/cryptonets-web-sdk';
//Front of DL scan
const { imageData, croppedDocument, croppedMugshot } = isValidPhotoID("PHOTO_ID_FRONT", documentCallback, false);
// Back of DL barcode scan
const { croppedBarcode, croppedDocument } = isValidPhotoID("PHOTO_ID_BACK", callback)
The isValidPhotoID function takes 3 parameters
Property | Description |
---|---|
docType | it can be either PHOTO_ID_BACK (back of the photo ID) or PHOTO_ID_FRONT (front of the photo ID) |
callback | returns the uuid of the portrait on the Front of the Photo ID |
doPredict | it is a boolean field wheter we are gonna do a predict on the image of front dl or not. Default value is true |
The function returns:
Front Document Scan (PHOTO_ID_FRONT)
imageData: ImageData datatype of the input image
croppedDocument: Uint8ClampedArray convertable to base64String of the cropped document. If document scan is unsuccessful, this will return null
croppedMugshot: Uint8ClampedArray convertable to base64String of the cropped face. If document scan is unsuccessful, this will return null
(Note: Please use utilty function below for converting images to base64 string.)
Front DL Callback Data returns:
{
conf_level: string,
cropped_face_channels: number,
cropped_face_height: number,
cropped_face_size: number,
cropped_face_width: number,
enroll_level: number,
face_valid: number,
face_validity_message: string,
guid: string,
int_doc_height: number,
int_doc_width: number,
op_message: string,
op_status: number,
payload_type: string,
predict_message: string,
predict_status: number,
uuid: string,
}
Back Document Scan (PHOTO_ID_BACK)
imageData: ImageData datatype of the input image
croppedDocument:: Uint8ClampedArray convertable to base64String of the cropped document. If barcode scan is unsuccessful, this will return null
croppedBarcode:: Uint8ClampedArray convertable to base64String of the cropped barcode. If barcode scan is unsuccessful, this will return null
Back DL Callback sample return value: Note: Variables might change depending on the barcode data.
{
"op_status": number,
"op_message": string,
"payload_type": string,
"barcode_conf_score": number,
"crop_barcode_width": number,
"crop_barcode_height": number,
"crop_doc_width": number,
"crop_doc_height": number,
"type": string,
"format": string,
"firstName": string,
"lastName": string,
"middleName": string,
"expirationDate": string,
"issueDate": string,
"dateOfBirth": string,
"gender": string,
"eyeColor": string,
"hairColor": string,
"height": string,
"streetAddress1": string,
"streetAddress2": string,
"RestStreetAddress1": string,
"RestStreetAddress2": string,
"city": string,
"state": string,
"postCode": string,
"issuingCountry": string,
"firstNameTruncation": string,
"placeOfBirth": string,
"auditInformation": string,
"inventoryControlNumber": string,
"lastNameAlias": string,
"firstNameAlias": string,
"suffixAlias": string,
"nameSuffix": string,
"namePrefix": string,
"barcode_key_string": string,
"barcodeHash64_string": string,
"barcodeHash128_string": string,
}
Utility function for convertion of image returned by front and back dl scan
convertCroppedImage()
This is a utility function that helps for converting returned image from FRONT DL SCAN and BACK DL SCAN
import { convertCroppedImage } from '@privateid/cryptonets-web-sdk';
// FRONT DL SCAN and BACK DL SCAN
// For converting imageData returned data from FRONT DL SCAN and BACK DL SCAN.
const InputImageBase64String = convertCroppedImage(imageData.data, imageData.width, imageData.height);
// FRONT DL SCAN
// For converting croppedDocument returned data from FRONT DL SCAN.
// (Note: We would need other variables that is returned in the callback data. crop_doc_width, crop_doc_height)
const FrontCroppedDocumentBase64String = convertCroppedImage(croppedDocument, crop_doc_width, crop_doc_height);
// For converting croppedMugshot returned data from FRONT DL SCAN.
// (Note: We would need other variables that is returned in the callback data. cropped_face_width and cropped_face_height)
const FrontCroppedMugshotBase64String = convertCroppedImage(croppedMugshot, cropped_face_width and cropped_face_height);
// BACK DL SCAN
// For converting croppedBarcode returned data from BACK DL SCAN.
// (Note: We would need other variables that is returned in the callback data. crop_barcode_width and crop_barcode_width)
const CroppedBarcodeBase64String = convertCroppedImage(croppedBarcode, crop_barcode_width, crop_barcode_height);
// For converting croppedDocument returned data from BACK DL SCAN.
// (Note: We would need other variables that is returned in the callback data. crop_doc_width and crop_doc_height)
const CroppedDocumentBase64String = convertCroppedImage(croppedDocument, crop_doc_width, crop_doc_height);
faceCompareLocal
This function compares 2 faces if they are matching. In the callback it is returning a conf_score (recommended threshold for faceCompare is 0.25)
import { faceCompareLocal } from '@privateid/cryptonets-web-sdk';
faceCompareLocal(callback, imageData1, imageData2, { input_image_format: "rgba" });
The faceCompareLocal function takes 4 parameters
Property | Description |
---|---|
callback | a function that will handle the result of compare returned |
imageData1 | imageData datatype of the first image |
imageData2 | imageData datatype of second image |
config | Additional configuration. Please enter { input_image_format: "rgba" } as a default |
Sample returned data in callback:
{
"error": number,
"distance_max": number,
"distance_mean": number,
"distance_min": number,
"conf_score": number,
"face_thresholds_count": number,
"face_thresholds": [
number,
number,
number
],
"result": number,
"valid_flag_a": number,
"valid_flag_b": number
}
Licensing Restriction: This product is not licensed for use in regulated gaming. To license in this market, please contact CentralAMS.
deleteUser
This function is used for deleting user with the uuid
import { deleteUser } from "@privateid/cryptonets-web-sdk";
deleteUser(uuid, callback)
Note: Please use Predict to get the user UUID you want to delete and pass it in
The function returns:
result: status of the validation of the document
Status | Description |
---|---|
0 | deletion is successful |
-1 | deletion is unsuccessful |
messege: deletion messege
checkPackageSupport
This function checks if the web browser supports WASM based on: https://www.lambdatest.com/web-technologies/wasm And also checks if WebRTC is supported based on: https://caniuse.com/?search=getusermedia
import { checkPackageSupport } from "@privateid/cryptonets-web-sdk";
checkPackageSupport();
The function returns:
status: status is a boolean when "True" the browser supports WASM and "False" browser does not support WASM
messege: Messege of the checking of package support.
API Utils
createUser
This function accepts { token
(CID or GAN Unique ID/PlayerID), phone
, email
, ... } and creates user.
import { createUser } from '@privateid/cryptonets-web-sdk';
createUser(parmas)
params = {
id?: string; // (CID or GAN Unique ID/PlayerID)
guid?: string;
phone: string;
phoneVerified?: boolean;
email?: string;
emailVerified?: boolean;
ssn4?: string;
ssn9?: string;
userConsent: boolean;
userConsentDate: string;
userFaceEnrollConsent?: boolean;
consentVersion: string;
portrait?: string;
};
sendEnrollSms
This function sends SMS to user's phone with a link to acquire front & back of Driver License from mobile. (also enroll face if faceEnrollConsent
is true).
From the redirect link in SMS, you can find query string code
. You can pass it through verifyToken function as a verification code to get user information.
You can use it if the webcam is lower than 2MP.
import { sendEnrollSms } from '@privateid/cryptonets-web-sdk';
sendEnrollSms({ id })
{
id: string; // (CID or GAN Unique ID/PlayerID)
}
verifyToken
This function gets the verification code as parameter and return the user information if it's valid code.
import { verifyToken } from '@privateid/cryptonets-web-sdk';
verifyToken({ code, type })
{
code: string; // verification code
type: ['phone', 'email'];
}
uploadPortrait
This function uploads user portrait image.
import { uploadPortrait } from '@privateid/cryptonets-web-sdk';
uploadPortrait({ id, portrait })
{
id: string; // (CID or GAN Unique ID/PlayerID)
portrait: string // Base64
}
uploadDL
This function uploads front & back of Driver Licence image.
import { uploadDL } from '@privateid/cryptonets-web-sdk';
// Uploading Front DL images
uploadDl({ id, type, image })
id: string //Required
type: "frontDLoriginal", "frontDLheadshot", "frontDLcropped"
image: string // Base64 //Require
// Uploading Back DL image
uploadDl({ id, type, image })
id: string //Required
type: "backDLoriginal", "backDLbarcode"
image: string // Base64 //Required
// Uploading Back DL barcode JSON
uploadDl({ id, type, barcode})
id : string //Required
type: "barcodeJson"
barcode: string //Required
Parameter | Description |
---|---|
id | Id to be set for customerID. (Required) |
type | "frontDLoriginal", "frontDLheadshot", "frontDLcropped", "backDLoriginal", "backDLbarcode" , "barcodeJson". (required) |
image | base64 string of image. (Required for all type exept 'barcodeJson') |
barcode | JSON string of the barcode data. (Required for type 'barcodeJson') |
updateUser
This function update user preferred data.
i.e. address
, city
, state
, country
, postalCode
, etc.
This information will be stored in preferred
field of User object in DB.
import { updateUser } from '@privateid/cryptonets-web-sdk';
updateUser({ id, attributes })
{
id: string; // (CID or GAN Unique ID/PlayerID)
attributes: {...}; //
}
getUserStatus
This function will return the status of user.
import { getUserStatus } from '@privateid/cryptonets-web-sdk';
getUserStatus({ id })
{
id: string; // (CID or GAN Unique ID/PlayerID)
}
Response
Name | Value | Description |
---|---|---|
userRegistered |
true , false
|
true if all user information provided for createUser function |
emailVerified |
true , false
|
Email verified for user |
phoneVerified |
true , false
|
Phone number verified for user |
manualPIIEntry |
true , false
|
true for manual data entry (no Scan ID) |
userScanID |
true , false
|
true Approved Scan ID |
validateSecurityToken
This function will validate the returned securityToken.
Note: Token are only valid for 5 minutes starting from the creation of token. After 5 minutes the token will be invalid.
import { validateSecurityToken } from '@privateid/cryptonets-web-sdk';
validateSecurityToken({ uuid, token })
{
uuid: string; // UUID of the user
token: string; // Token from the api call i.e. enroll1Fa/predict1Fa
}
Response
Name | Value | Description |
---|---|---|
securityToken | string | The securityToken passed in the API call. |
securityTokenStatus | '1','0' | '1' being TRUE means securityToken is valid. '0' being FALSE means securityToken is invalid. |