curve25519.h
Functions
Name | |
---|---|
int | wc_curve25519_make_key(WC_RNG * rng, int keysize, curve25519_key * key) This function generates a Curve25519 key using the given random number generator, rng, of the size given (keysize), and stores it in the given curve25519_key structure. It should be called after the key structure has been initialized through wc_curve25519_init(). |
int | wc_curve25519_shared_secret(curve25519_key * private_key, curve25519_key * public_key, byte * out, word32 * outlen) This function computes a shared secret key given a secret private key and a received public key. It stores the generated secret key in the buffer out and assigns the variable of the secret key to outlen. Only supports big endian. |
int | wc_curve25519_shared_secret_ex(curve25519_key * private_key, curve25519_key * public_key, byte * out, word32 * outlen, int endian) This function computes a shared secret key given a secret private key and a received public key. It stores the generated secret key in the buffer out and assigns the variable of the secret key to outlen. Supports both big and little endian. |
int | wc_curve25519_init(curve25519_key * key) This function initializes a Curve25519 key. It should be called before generating a key for the structure. |
void | wc_curve25519_free(curve25519_key * key) This function frees a Curve25519 object. |
int | wc_curve25519_import_private(const byte * priv, word32 privSz, curve25519_key * key) This function imports a curve25519 private key only. (Big endian). |
int | wc_curve25519_import_private_ex(const byte * priv, word32 privSz, curve25519_key * key, int endian) curve25519 private key import only. (Big or Little endian). |
int | wc_curve25519_import_private_raw(const byte * priv, word32 privSz, const byte * pub, word32 pubSz, curve25519_key * key) This function imports a public-private key pair into a curve25519_key structure. Big endian only. |
int | wc_curve25519_import_private_raw_ex(const byte * priv, word32 privSz, const byte * pub, word32 pubSz, curve25519_key * key, int endian) This function imports a public-private key pair into a curve25519_key structure. Supports both big and little endian. |
int | wc_curve25519_export_private_raw(curve25519_key * key, byte * out, word32 * outLen) This function exports a private key from a curve25519_key structure and stores it in the given out buffer. It also sets outLen to be the size of the exported key. Big Endian only. |
int | wc_curve25519_export_private_raw_ex(curve25519_key * key, byte * out, word32 * outLen, int endian) This function exports a private key from a curve25519_key structure and stores it in the given out buffer. It also sets outLen to be the size of the exported key. Can specify whether it's big or little endian. |
int | wc_curve25519_import_public(const byte * in, word32 inLen, curve25519_key * key) This function imports a public key from the given in buffer and stores it in the curve25519_key structure. |
int | wc_curve25519_import_public_ex(const byte * in, word32 inLen, curve25519_key * key, int endian) This function imports a public key from the given in buffer and stores it in the curve25519_key structure. |
int | wc_curve25519_check_public(const byte * pub, word32 pubSz, int endian) This function checks that a public key buffer holds a valid Curve25519 key value given the endian ordering. |
int | wc_curve25519_export_public(curve25519_key * key, byte * out, word32 * outLen) This function exports a public key from the given key structure and stores the result in the out buffer. Big endian only. |
int | wc_curve25519_export_public_ex(curve25519_key * key, byte * out, word32 * outLen, int endian) This function exports a public key from the given key structure and stores the result in the out buffer. Supports both big and little endian. |
int | wc_curve25519_export_key_raw(curve25519_key * key, byte * priv, word32 * privSz, byte * pub, word32 * pubSz) Export Curve25519 key pair. Big endian only. |
int | wc_curve25519_export_key_raw_ex(curve25519_key * key, byte * priv, word32 * privSz, byte * pub, word32 * pubSz, int endian) Export curve25519 key pair. Big or little endian. |
int | wc_curve25519_size(curve25519_key * key) This function returns the key size of the given key structure. |
Functions Documentation
function wc_curve25519_make_key
int wc_curve25519_make_key(
WC_RNG * rng,
int keysize,
curve25519_key * key
)
This function generates a Curve25519 key using the given random number generator, rng, of the size given (keysize), and stores it in the given curve25519_key structure. It should be called after the key structure has been initialized through wc_curve25519_init().
Parameters:
- rng Pointer to the RNG object used to generate the ecc key.
- keysize Size of the key to generate. Must be 32 bytes for curve25519.
- key Pointer to the curve25519_key structure in which to store the generated key.
See: wc_curve25519_init
Return:
- 0 Returned on successfully generating the key and and storing it in the given curve25519_key structure.
- ECC_BAD_ARG_E Returned if the input keysize does not correspond to the keysize for a curve25519 key (32 bytes).
- RNG_FAILURE_E Returned if the rng internal status is not DRBG_OK or if there is in generating the next random block with rng.
- BAD_FUNC_ARG Returned if any of the input parameters passed in are NULL.
Example
int ret;
curve25519_key key;
wc_curve25519_init(&key); // initialize key
WC_RNG rng;
wc_InitRng(&rng); // initialize random number generator
ret = wc_curve25519_make_key(&rng, 32, &key);
if (ret != 0) {
// error making Curve25519 key
}
function wc_curve25519_shared_secret
int wc_curve25519_shared_secret(
curve25519_key * private_key,
curve25519_key * public_key,
byte * out,
word32 * outlen
)
This function computes a shared secret key given a secret private key and a received public key. It stores the generated secret key in the buffer out and assigns the variable of the secret key to outlen. Only supports big endian.
Parameters:
- private_key Pointer to the curve25519_key structure initialized with the user’s private key.
- public_key Pointer to the curve25519_key structure containing the received public key.
- out Pointer to a buffer in which to store the 32 byte computed secret key.
- outlen Pointer in which to store the length written to the output buffer.
See:
Return:
- 0 Returned on successfully computing a shared secret key.
- BAD_FUNC_ARG Returned if any of the input parameters passed in are NULL.
- ECC_BAD_ARG_E Returned if the first bit of the public key is set, to avoid implementation fingerprinting.
Example
int ret;
byte sharedKey[32];
word32 keySz;
curve25519_key privKey, pubKey;
// initialize both keys
ret = wc_curve25519_shared_secret(&privKey, &pubKey, sharedKey, &keySz);
if (ret != 0) {
// error generating shared key
}
function wc_curve25519_shared_secret_ex
int wc_curve25519_shared_secret_ex(
curve25519_key * private_key,
curve25519_key * public_key,
byte * out,
word32 * outlen,
int endian
)
This function computes a shared secret key given a secret private key and a received public key. It stores the generated secret key in the buffer out and assigns the variable of the secret key to outlen. Supports both big and little endian.
Parameters:
- private_key Pointer to the curve25519_key structure initialized with the user’s private key.
- public_key Pointer to the curve25519_key structure containing the received public key.
- out Pointer to a buffer in which to store the 32 byte computed secret key.
- pinout] outlen Pointer in which to store the length written to the output buffer.
- endian EC25519_BIG_ENDIAN or EC25519_LITTLE_ENDIAN to set which form to use.
See:
Return:
- 0 Returned on successfully computing a shared secret key.
- BAD_FUNC_ARG Returned if any of the input parameters passed in are NULL.
- ECC_BAD_ARG_E Returned if the first bit of the public key is set, to avoid implementation fingerprinting.
Example
int ret;
byte sharedKey[32];
word32 keySz;
curve25519_key privKey, pubKey;
// initialize both keys
ret = wc_curve25519_shared_secret_ex(&privKey, &pubKey, sharedKey, &keySz,
EC25519_BIG_ENDIAN);
if (ret != 0) {
// error generating shared key
}
function wc_curve25519_init
int wc_curve25519_init(
curve25519_key * key
)
This function initializes a Curve25519 key. It should be called before generating a key for the structure.
Parameters:
- key Pointer to the curve25519_key structure to initialize.
Return:
- 0 Returned on successfully initializing the curve25519_key structure.
- BAD_FUNC_ARG Returned when key is NULL.
Example
curve25519_key key;
wc_curve25519_init(&key); // initialize key
// make key and proceed to encryption
function wc_curve25519_free
void wc_curve25519_free(
curve25519_key * key
)
This function frees a Curve25519 object.
Parameters:
- key Pointer to the key object to free.
See:
Example
curve25519_key privKey;
// initialize key, use it to generate shared secret key
wc_curve25519_free(&privKey);
function wc_curve25519_import_private
int wc_curve25519_import_private(
const byte * priv,
word32 privSz,
curve25519_key * key
)
This function imports a curve25519 private key only. (Big endian).
Parameters:
- priv Pointer to a buffer containing the private key to import.
- privSz Length of the private key to import.
- key Pointer to the structure in which to store the imported key.
See:
Return:
- 0 Returned on successfully importing private key.
- BAD_FUNC_ARG Returns if key or priv is null.
- ECC_BAD_ARG_E Returns if privSz is not equal to CURVE25519_KEY_SIZE.
Example
int ret;
byte priv[] = { Contents of private key };
curve25519_key key;
wc_curve25519_init(&key);
ret = wc_curve25519_import_private(priv, sizeof(priv), &key);
if (ret != 0) {
// error importing keys
}
function wc_curve25519_import_private_ex
int wc_curve25519_import_private_ex(
const byte * priv,
word32 privSz,
curve25519_key * key,
int endian
)
curve25519 private key import only. (Big or Little endian).
Parameters:
- priv Pointer to a buffer containing the private key to import.
- privSz Length of the private key to import.
- key Pointer to the structure in which to store the imported key.
- endian EC25519_BIG_ENDIAN or EC25519_LITTLE_ENDIAN to set which form to use.
See:
Return:
- 0 Returned on successfully importing private key.
- BAD_FUNC_ARG Returns if key or priv is null.
- ECC_BAD_ARG_E Returns if privSz is not equal to CURVE25519_KEY_SIZE.
Example
int ret;
byte priv[] = { // Contents of private key };
curve25519_key key;
wc_curve25519_init(&key);
ret = wc_curve25519_import_private_ex(priv, sizeof(priv), &key,
EC25519_BIG_ENDIAN);
if (ret != 0) {
// error importing keys
}
function wc_curve25519_import_private_raw
int wc_curve25519_import_private_raw(
const byte * priv,
word32 privSz,
const byte * pub,
word32 pubSz,
curve25519_key * key
)
This function imports a public-private key pair into a curve25519_key structure. Big endian only.
Parameters:
- priv Pointer to a buffer containing the private key to import.
- privSz Length of the private key to import.
- pub Pointer to a buffer containing the public key to import.
- pubSz Length of the public key to import.
- key Pointer to the structure in which to store the imported keys.
See:
- wc_curve25519_init
- wc_curve25519_make_key
- wc_curve25519_import_public
- wc_curve25519_export_private_raw
Return:
- 0 Returned on importing into the curve25519_key structure
- BAD_FUNC_ARG Returns if any of the input parameters are null.
- ECC_BAD_ARG_E Returned if the input key’s key size does not match the public or private key sizes.
Example
int ret;
byte priv[32];
byte pub[32];
// initialize with public and private keys
curve25519_key key;
wc_curve25519_init(&key);
// initialize key
ret = wc_curve25519_import_private_raw(&priv, sizeof(priv), pub,
sizeof(pub), &key);
if (ret != 0) {
// error importing keys
}
function wc_curve25519_import_private_raw_ex
int wc_curve25519_import_private_raw_ex(
const byte * priv,
word32 privSz,
const byte * pub,
word32 pubSz,
curve25519_key * key,
int endian
)
This function imports a public-private key pair into a curve25519_key structure. Supports both big and little endian.
Parameters:
- priv Pointer to a buffer containing the private key to import.
- privSz Length of the private key to import.
- pub Pointer to a buffer containing the public key to import.
- pubSz Length of the public key to import.
- key Pointer to the structure in which to store the imported keys.
- endian EC25519_BIG_ENDIAN or EC25519_LITTLE_ENDIAN to set which form to use.
See:
- wc_curve25519_init
- wc_curve25519_make_key
- wc_curve25519_import_public
- wc_curve25519_export_private_raw
- wc_curve25519_import_private_raw
Return:
- 0 Returned on importing into the curve25519_key structure
- BAD_FUNC_ARG Returns if any of the input parameters are null.
- ECC_BAD_ARG_E Returned if or the input key’s key size does not match the public or private key sizes
Example
int ret;
byte priv[32];
byte pub[32];
// initialize with public and private keys
curve25519_key key;
wc_curve25519_init(&key);
// initialize key
ret = wc_curve25519_import_private_raw_ex(&priv, sizeof(priv), pub,
sizeof(pub), &key, EC25519_BIG_ENDIAN);
if (ret != 0) {
// error importing keys
}
function wc_curve25519_export_private_raw
int wc_curve25519_export_private_raw(
curve25519_key * key,
byte * out,
word32 * outLen
)
This function exports a private key from a curve25519_key structure and stores it in the given out buffer. It also sets outLen to be the size of the exported key. Big Endian only.
Parameters:
- key Pointer to the structure from which to export the key.
- out Pointer to the buffer in which to store the exported key.
- outLen On in, is the size of the out in bytes. On out, will store the bytes written to the output buffer.
See:
- wc_curve25519_init
- wc_curve25519_make_key
- wc_curve25519_import_private_raw
- wc_curve25519_export_private_raw_ex
Return:
- 0 Returned on successfully exporting the private key from the curve25519_key structure.
- BAD_FUNC_ARG Returned if any input parameters are NULL.
- ECC_BAD_ARG_E Returned if wc_curve25519_size() is not equal to key.
Example
int ret;
byte priv[32];
int privSz;
curve25519_key key;
// initialize and make key
ret = wc_curve25519_export_private_raw(&key, priv, &privSz);
if (ret != 0) {
// error exporting key
}
function wc_curve25519_export_private_raw_ex
int wc_curve25519_export_private_raw_ex(
curve25519_key * key,
byte * out,
word32 * outLen,
int endian
)
This function exports a private key from a curve25519_key structure and stores it in the given out buffer. It also sets outLen to be the size of the exported key. Can specify whether it's big or little endian.
Parameters:
- key Pointer to the structure from which to export the key.
- out Pointer to the buffer in which to store the exported key.
- outLen On in, is the size of the out in bytes. On out, will store the bytes written to the output buffer.
- endian EC25519_BIG_ENDIAN or EC25519_LITTLE_ENDIAN to set which form to use.
See:
- wc_curve25519_init
- wc_curve25519_make_key
- wc_curve25519_import_private_raw
- wc_curve25519_export_private_raw
- wc_curve25519_size
Return:
- 0 Returned on successfully exporting the private key from the curve25519_key structure.
- BAD_FUNC_ARG Returned if any input parameters are NULL.
- ECC_BAD_ARG_E Returned if wc_curve25519_size() is not equal to key.
Example
int ret;
byte priv[32];
int privSz;
curve25519_key key;
// initialize and make key
ret = wc_curve25519_export_private_raw_ex(&key, priv, &privSz,
EC25519_BIG_ENDIAN);
if (ret != 0) {
// error exporting key
}
function wc_curve25519_import_public
int wc_curve25519_import_public(
const byte * in,
word32 inLen,
curve25519_key * key
)
This function imports a public key from the given in buffer and stores it in the curve25519_key structure.
Parameters:
- in Pointer to the buffer containing the public key to import.
- inLen Length of the public key to import.
- key Pointer to the curve25519_key structure in which to store the key.
See:
- wc_curve25519_init
- wc_curve25519_export_public
- wc_curve25519_import_private_raw
- wc_curve25519_import_public_ex
- wc_curve25519_check_public
- wc_curve25519_size
Return:
- 0 Returned on successfully importing the public key into the curve25519_key structure.
- ECC_BAD_ARG_E Returned if the inLen parameter does not match the key size of the key structure.
- BAD_FUNC_ARG Returned if any of the input parameters are NULL.
Example
int ret;
byte pub[32];
// initialize pub with public key
curve25519_key key;
// initialize key
ret = wc_curve25519_import_public(pub,sizeof(pub), &key);
if (ret != 0) {
// error importing key
}
function wc_curve25519_import_public_ex
int wc_curve25519_import_public_ex(
const byte * in,
word32 inLen,
curve25519_key * key,
int endian
)
This function imports a public key from the given in buffer and stores it in the curve25519_key structure.
Parameters:
- in Pointer to the buffer containing the public key to import.
- inLen Length of the public key to import.
- key Pointer to the curve25519_key structure in which to store the key.
- endian EC25519_BIG_ENDIAN or EC25519_LITTLE_ENDIAN to set which form to use.
See:
- wc_curve25519_init
- wc_curve25519_export_public
- wc_curve25519_import_private_raw
- wc_curve25519_import_public
- wc_curve25519_check_public
- wc_curve25519_size
Return:
- 0 Returned on successfully importing the public key into the curve25519_key structure.
- ECC_BAD_ARG_E Returned if the inLen parameter does not match the key size of the key structure.
- BAD_FUNC_ARG Returned if any of the input parameters are NULL.
Example
int ret;
byte pub[32];
// initialize pub with public key
curve25519_key key;
// initialize key
ret = wc_curve25519_import_public_ex(pub, sizeof(pub), &key,
EC25519_BIG_ENDIAN);
if (ret != 0) {
// error importing key
}
function wc_curve25519_check_public
int wc_curve25519_check_public(
const byte * pub,
word32 pubSz,
int endian
)
This function checks that a public key buffer holds a valid Curve25519 key value given the endian ordering.
Parameters:
- pub Pointer to the buffer containing the public key to check.
- pubLen Length of the public key to check.
- endian EC25519_BIG_ENDIAN or EC25519_LITTLE_ENDIAN to set which form to use.
See:
Return:
- 0 Returned when the public key value is valid.
- ECC_BAD_ARG_E Returned if the public key value is not valid.
- BAD_FUNC_ARG Returned if any of the input parameters are NULL.
Example
int ret;
byte pub[] = { Contents of public key };
ret = wc_curve25519_check_public_ex(pub, sizeof(pub), EC25519_BIG_ENDIAN);
if (ret != 0) {
// error importing key
}
function wc_curve25519_export_public
int wc_curve25519_export_public(
curve25519_key * key,
byte * out,
word32 * outLen
)
This function exports a public key from the given key structure and stores the result in the out buffer. Big endian only.
Parameters:
- key Pointer to the curve25519_key structure in from which to export the key.
- out Pointer to the buffer in which to store the public key.
- outLen On in, is the size of the out in bytes. On out, will store the bytes written to the output buffer.
See:
Return:
- 0 Returned on successfully exporting the public key from the curve25519_key structure.
- ECC_BAD_ARG_E Returned if outLen is less than CURVE25519_PUB_KEY_SIZE.
- BAD_FUNC_ARG Returned if any of the input parameters are NULL.
Example
int ret;
byte pub[32];
int pubSz;
curve25519_key key;
// initialize and make key
ret = wc_curve25519_export_public(&key, pub, &pubSz);
if (ret != 0) {
// error exporting key
}
function wc_curve25519_export_public_ex
int wc_curve25519_export_public_ex(
curve25519_key * key,
byte * out,
word32 * outLen,
int endian
)
This function exports a public key from the given key structure and stores the result in the out buffer. Supports both big and little endian.
Parameters:
- key Pointer to the curve25519_key structure in from which to export the key.
- out Pointer to the buffer in which to store the public key.
- outLen On in, is the size of the out in bytes. On out, will store the bytes written to the output buffer.
- endian EC25519_BIG_ENDIAN or EC25519_LITTLE_ENDIAN to set which form to use.
See:
Return:
- 0 Returned on successfully exporting the public key from the curve25519_key structure.
- ECC_BAD_ARG_E Returned if outLen is less than CURVE25519_PUB_KEY_SIZE.
- BAD_FUNC_ARG Returned if any of the input parameters are NULL.
Example
int ret;
byte pub[32];
int pubSz;
curve25519_key key;
// initialize and make key
ret = wc_curve25519_export_public_ex(&key, pub, &pubSz, EC25519_BIG_ENDIAN);
if (ret != 0) {
// error exporting key
}
function wc_curve25519_export_key_raw
int wc_curve25519_export_key_raw(
curve25519_key * key,
byte * priv,
word32 * privSz,
byte * pub,
word32 * pubSz
)
Export Curve25519 key pair. Big endian only.
Parameters:
- key Pointer to the curve448_key structure in from which to export the key pair.
- priv Pointer to the buffer in which to store the private key.
- privSz On in, is the size of the priv buffer in bytes. On out, will store the bytes written to the priv buffer.
- pub Pointer to the buffer in which to store the public key.
- pubSz On in, is the size of the pub buffer in bytes. On out, will store the bytes written to the pub buffer.
See:
Return:
- 0 Returned on successfully exporting the key pair from the curve25519_key structure.
- BAD_FUNC_ARG Returned if any input parameters are NULL.
- ECC_BAD_ARG_E Returned if privSz is less than CURVE25519_KEY_SIZE or pubSz is less than CURVE25519_PUB_KEY_SIZE.
Example
int ret;
byte pub[32];
byte priv[32];
int pubSz;
int privSz;
curve25519_key key;
// initialize and make key
ret = wc_curve25519_export_key_raw(&key, priv, &privSz, pub, &pubSz);
if (ret != 0) {
// error exporting key
}
function wc_curve25519_export_key_raw_ex
int wc_curve25519_export_key_raw_ex(
curve25519_key * key,
byte * priv,
word32 * privSz,
byte * pub,
word32 * pubSz,
int endian
)
Export curve25519 key pair. Big or little endian.
Parameters:
- key Pointer to the curve448_key structure in from which to export the key pair.
- priv Pointer to the buffer in which to store the private key.
- privSz On in, is the size of the priv buffer in bytes. On out, will store the bytes written to the priv buffer.
- pub Pointer to the buffer in which to store the public key.
- pubSz On in, is the size of the pub buffer in bytes. On out, will store the bytes written to the pub buffer.
- endian EC25519_BIG_ENDIAN or EC25519_LITTLE_ENDIAN to set which form to use.
See:
Return:
- 0 Returned on successfully exporting the key pair from the curve25519_key structure.
- BAD_FUNC_ARG Returned if any input parameters are NULL.
- ECC_BAD_ARG_E Returned if privSz is less than CURVE25519_KEY_SIZE or pubSz is less than CURVE25519_PUB_KEY_SIZE.
Example
int ret;
byte pub[32];
byte priv[32];
int pubSz;
int privSz;
curve25519_key key;
// initialize and make key
ret = wc_curve25519_export_key_raw_ex(&key,priv, &privSz, pub, &pubSz,
EC25519_BIG_ENDIAN);
if (ret != 0) {
// error exporting key
}
function wc_curve25519_size
int wc_curve25519_size(
curve25519_key * key
)
This function returns the key size of the given key structure.
Parameters:
- key Pointer to the curve25519_key structure in for which to determine the key size.
See:
Return:
- Success Given a valid, initialized curve25519_key structure, returns the size of the key.
- 0 Returned if key is NULL
Example
int keySz;
curve25519_key key;
// initialize and make key
keySz = wc_curve25519_size(&key);
Source code
int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key);
int wc_curve25519_shared_secret(curve25519_key* private_key,
curve25519_key* public_key,
byte* out, word32* outlen);
int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
curve25519_key* public_key,
byte* out, word32* outlen, int endian);
int wc_curve25519_init(curve25519_key* key);
void wc_curve25519_free(curve25519_key* key);
int wc_curve25519_import_private(const byte* priv, word32 privSz,
curve25519_key* key);
int wc_curve25519_import_private_ex(const byte* priv, word32 privSz,
curve25519_key* key, int endian);
int wc_curve25519_import_private_raw(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, curve25519_key* key);
int wc_curve25519_import_private_raw_ex(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz,
curve25519_key* key, int endian);
int wc_curve25519_export_private_raw(curve25519_key* key, byte* out,
word32* outLen);
int wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out,
word32* outLen, int endian);
int wc_curve25519_import_public(const byte* in, word32 inLen,
curve25519_key* key);
int wc_curve25519_import_public_ex(const byte* in, word32 inLen,
curve25519_key* key, int endian);
int wc_curve25519_check_public(const byte* pub, word32 pubSz, int endian);
int wc_curve25519_export_public(curve25519_key* key, byte* out, word32* outLen);
int wc_curve25519_export_public_ex(curve25519_key* key, byte* out,
word32* outLen, int endian);
int wc_curve25519_export_key_raw(curve25519_key* key,
byte* priv, word32 *privSz,
byte* pub, word32 *pubSz);
int wc_curve25519_export_key_raw_ex(curve25519_key* key,
byte* priv, word32 *privSz,
byte* pub, word32 *pubSz,
int endian);
int wc_curve25519_size(curve25519_key* key);
Updated on 2024-11-21 at 01:17:07 +0000