This commit is contained in:
Jay D Dee
2017-07-24 21:38:32 -04:00
parent f8907677f6
commit ec4f6028a2
18 changed files with 158 additions and 183 deletions

View File

@@ -117,7 +117,7 @@ cpuminer_SOURCES = \
algo/simd/sse2/vector.c \ algo/simd/sse2/vector.c \
algo/skein/skein.c \ algo/skein/skein.c \
algo/skein/skein2.c \ algo/skein/skein2.c \
algo/s3.c \ algo/skunk.c \
algo/tiger/sph_tiger.c \ algo/tiger/sph_tiger.c \
algo/timetravel.c \ algo/timetravel.c \
algo/timetravel10.c \ algo/timetravel10.c \

View File

@@ -40,7 +40,7 @@ Supported Algorithms
lbry LBC, LBRY Credits lbry LBC, LBRY Credits
luffa Luffa luffa Luffa
lyra2re lyra2 lyra2re lyra2
lyra2rev2 lyrav2, Vertcoin lyra2rev2 lyra2v2, Vertcoin
lyra2z Zcoin (XZC) lyra2z Zcoin (XZC)
lyra2z330 Lyra2 330 rows, Zoin (ZOI) lyra2z330 Lyra2 330 rows, Zoin (ZOI)
m7m Magi (XMG) m7m Magi (XMG)
@@ -59,8 +59,10 @@ Supported Algorithms
shavite3 Shavite3 shavite3 Shavite3
skein Skein+Sha (Skeincoin) skein Skein+Sha (Skeincoin)
skein2 Double Skein (Woodcoin) skein2 Double Skein (Woodcoin)
skunk Signatum (SIGT)
timetravel Machinecoin (MAC) timetravel Machinecoin (MAC)
timetravel10 Bitcore timetravel10 Bitcore
tribus Denarius (DNR)
vanilla blake256r8vnl (VCash) vanilla blake256r8vnl (VCash)
veltor veltor
whirlpool whirlpool

View File

@@ -49,7 +49,8 @@ pthreads
zlib zlib
SHA support on AMD Ryzen CPUs requires gcc version 5 or higher and openssl 1.1 SHA support on AMD Ryzen CPUs requires gcc version 5 or higher and openssl 1.1
or higher. Additional compile options may also be required such as or higher. Some older versions of openssl may also work, it is known to work
with Ubuntu 16.04. Additional compile options may also be required such as
"-march-znver1" or "-msha". "-march-znver1" or "-msha".
Extract cpuminer source. Extract cpuminer source.
@@ -125,6 +126,12 @@ Support for even older x86_64 without AES_NI or SSE2 is not availble.
Change Log Change Log
---------- ----------
v3.6.7
Skunk algo added.
Tribus a little faster.
Minor restructuring.
v3.6.6 v3.6.6
added tribus algo for Denarius (DNR) added tribus algo for Denarius (DNR)

View File

@@ -192,7 +192,7 @@ bool register_algo_gate( int algo, algo_gate_t *gate )
case ALGO_SHAVITE3: register_shavite_algo ( gate ); break; case ALGO_SHAVITE3: register_shavite_algo ( gate ); break;
case ALGO_SKEIN: register_skein_algo ( gate ); break; case ALGO_SKEIN: register_skein_algo ( gate ); break;
case ALGO_SKEIN2: register_skein2_algo ( gate ); break; case ALGO_SKEIN2: register_skein2_algo ( gate ); break;
case ALGO_S3: register_s3_algo ( gate ); break; case ALGO_SKUNK: register_skunk_algo ( gate ); break;
case ALGO_TIMETRAVEL: register_timetravel_algo ( gate ); break; case ALGO_TIMETRAVEL: register_timetravel_algo ( gate ); break;
case ALGO_TIMETRAVEL10: register_timetravel10_algo( gate ); break; case ALGO_TIMETRAVEL10: register_timetravel10_algo( gate ); break;
case ALGO_TRIBUS: register_tribus_algo ( gate ); break; case ALGO_TRIBUS: register_tribus_algo ( gate ); break;

View File

@@ -21,7 +21,7 @@
#include "brg_endian.h" #include "brg_endian.h"
#define NEED_UINT_64T #define NEED_UINT_64T
#include "brg_types.h" #include "algo/sha/brg_types.h"
/* some sizes (number of bytes) */ /* some sizes (number of bytes) */
#define ROWS (8) #define ROWS (8)

View File

@@ -35,7 +35,7 @@ typedef crypto_uint64 u64;
#include "brg_endian.h" #include "brg_endian.h"
#define NEED_UINT_64T #define NEED_UINT_64T
#include "brg_types.h" #include "algo/sha/brg_types.h"
#ifdef IACA_TRACE #ifdef IACA_TRACE
#include IACA_MARKS #include IACA_MARKS

View File

@@ -22,15 +22,12 @@
*/ */
#include <emmintrin.h> #include <emmintrin.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "algo/sha/sha3-defs.h"
typedef __m128i word128; /*word128 defines a 128-bit SSE2 word*/ typedef __m128i word128; /*word128 defines a 128-bit SSE2 word*/
typedef unsigned char BitSequence;
typedef unsigned long long DataLength;
typedef enum {jhSUCCESS = 0, jhFAIL = 1, jhBAD_HASHLEN = 2} jhReturn; typedef enum {jhSUCCESS = 0, jhFAIL = 1, jhBAD_HASHLEN = 2} jhReturn;
/*define data alignment for different C compilers*/ /*define data alignment for different C compilers*/

View File

@@ -21,8 +21,9 @@
#define LYRA2_H_ #define LYRA2_H_
#include <stdint.h> #include <stdint.h>
#include "algo/sha/sha3-defs.h"
typedef unsigned char byte; //typedef unsigned char byte;
//Block length required so Blake2's Initialization Vector (IV) is not overwritten (THIS SHOULD NOT BE MODIFIED) //Block length required so Blake2's Initialization Vector (IV) is not overwritten (THIS SHOULD NOT BE MODIFIED)
#define BLOCK_LEN_BLAKE2_SAFE_INT64 8 //512 bits (=64 bytes, =8 uint64_t) #define BLOCK_LEN_BLAKE2_SAFE_INT64 8 //512 bits (=64 bytes, =8 uint64_t)

116
algo/s3.c
View File

@@ -1,116 +0,0 @@
#include "miner.h"
#include "algo-gate-api.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "algo/skein/sph_skein.h"
#include "algo/shavite/sph_shavite.h"
#include "algo/simd/sph_simd.h"
void s3hash(void *output, const void *input)
{
sph_shavite512_context ctx_shavite;
sph_simd512_context ctx_simd;
sph_skein512_context ctx_skein;
unsigned char _ALIGN(128) hash[64];
sph_shavite512_init(&ctx_shavite);
sph_shavite512(&ctx_shavite, input, 80);
sph_shavite512_close(&ctx_shavite, (void*)hash);
sph_simd512_init(&ctx_simd);
sph_simd512(&ctx_simd, (const void*)hash, 64);
sph_simd512_close(&ctx_simd, (void*)hash);
sph_skein512_init(&ctx_skein);
sph_skein512(&ctx_skein, (const void*)hash, 64);
sph_skein512_close(&ctx_skein, (void*)hash);
memcpy(output, hash, 32);
}
int scanhash_s3(int thr_id, struct work *work, uint32_t max_nonce,
uint64_t *hashes_done)
{
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t n = pdata[19] - 1;
const uint32_t first_nonce = pdata[19];
const uint32_t Htarg = ptarget[7];
uint32_t _ALIGN(32) hash64[8];
uint32_t endiandata[32];
uint64_t htmax[] = {
0,
0xF,
0xFF,
0xFFF,
0xFFFF,
0x10000000
};
uint32_t masks[] = {
0xFFFFFFFF,
0xFFFFFFF0,
0xFFFFFF00,
0xFFFFF000,
0xFFFF0000,
0
};
// we need bigendian data...
for (int kk=0; kk < 32; kk++) {
be32enc(&endiandata[kk], ((uint32_t*)pdata)[kk]);
};
#ifdef DEBUG_ALGO
printf("[%d] Htarg=%X\n", thr_id, Htarg);
#endif
for (int m=0; m < 6; m++) {
if (Htarg <= htmax[m]) {
uint32_t mask = masks[m];
do {
pdata[19] = ++n;
be32enc(&endiandata[19], n);
s3hash(hash64, endiandata);
#ifndef DEBUG_ALGO
if ((!(hash64[7] & mask)) && fulltest(hash64, ptarget)) {
*hashes_done = n - first_nonce + 1;
return true;
}
#else
if (!(n % 0x1000) && !thr_id) printf(".");
if (!(hash64[7] & mask)) {
printf("[%d]",thr_id);
if (fulltest(hash64, ptarget)) {
*hashes_done = n - first_nonce + 1;
return true;
}
}
#endif
} while (n < max_nonce && !work_restart[thr_id].restart);
// see blake.c if else to understand the loop on htmax => mask
break;
}
}
*hashes_done = n - first_nonce + 1;
pdata[19] = n;
return 0;
}
bool register_s3_algo( algo_gate_t* gate )
{
algo_not_tested();
gate->scanhash = (void*)&scanhash_s3;
gate->hash = (void*)&s3hash;
// gate->get_max64 = &s3_get_max64;
return true;
};

View File

@@ -780,7 +780,7 @@ bool register_scrypt_algo( algo_gate_t* gate )
{ {
gate->miner_thread_init =(void*)&scrypt_miner_thread_init; gate->miner_thread_init =(void*)&scrypt_miner_thread_init;
gate->scanhash = (void*)&scanhash_scrypt; gate->scanhash = (void*)&scanhash_scrypt;
gate->hash = (void*)&scrypt_1024_1_1_256_24way; // gate->hash = (void*)&scrypt_1024_1_1_256_24way;
gate->set_target = (void*)&scrypt_set_target; gate->set_target = (void*)&scrypt_set_target;
gate->get_max64 = (void*)&scrypt_get_max64; gate->get_max64 = (void*)&scrypt_get_max64;

View File

@@ -8,28 +8,12 @@
#define DATA_ALIGN(x) __declspec(align(16)) x #define DATA_ALIGN(x) __declspec(align(16)) x
#endif #endif
#include "compat.h" #include "simd-compat.h"
#include "algo/sha/sha3-defs.h" #include "algo/sha/sha3-defs.h"
/* /*
* NIST API Specific types. * NIST API Specific types.
*/ */
//typedef unsigned char BitSequence;
//#ifdef HAS_64
// typedef u64 DataLength;
//#else
// typedef unsigned long DataLength;
//#endif
// can't find u32 or fft-t
#include <stdint.h>
typedef uint32_t u32;
typedef int fft_t;
//typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHBITLEN = 2} HashReturn;
typedef struct { typedef struct {
unsigned int hashbitlen; unsigned int hashbitlen;
unsigned int blocksize; unsigned int blocksize;

View File

@@ -1,5 +1,5 @@
#ifndef __COMPAT_H__ #ifndef __SIMD_COMPAT_H__
#define __COMPAT_H__ #define __SIMD_COMPAT_H__
#include <limits.h> #include <limits.h>
@@ -24,14 +24,7 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include "algo/sha/brg_types.h"
#ifdef UINT32_MAX
typedef uint32_t u32;
#else
typedef uint_fast32_t u32;
#endif
typedef unsigned long long u64;
#define C32(x) ((u32)(x)) #define C32(x) ((u32)(x))

102
algo/skunk.c Normal file
View File

@@ -0,0 +1,102 @@
#include "miner.h"
#include "algo-gate-api.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "algo/gost/sph_gost.h"
#include "algo/skein/sph_skein.h"
#include "algo/fugue/sph_fugue.h"
#include "algo/cubehash/sse2/cubehash_sse2.h"
typedef struct {
sph_skein512_context skein;
cubehashParam cube;
sph_fugue512_context fugue;
sph_gost512_context gost;
} skunk_ctx_holder;
static __thread skunk_ctx_holder skunk_ctx;
void skunkhash( void *output, const void *input )
{
unsigned char hash[128] __attribute__ ((aligned (64)));
skunk_ctx_holder ctx __attribute__ ((aligned (64)));
memcpy( &ctx, &skunk_ctx, sizeof(skunk_ctx) );
sph_skein512( &ctx.skein, input+64, 16 );
sph_skein512_close( &ctx.skein, (void*) hash );
cubehashUpdateDigest( &ctx.cube, (byte*) hash, (const byte*)hash, 64 );
sph_fugue512( &ctx.fugue, hash, 64 );
sph_fugue512_close( &ctx.fugue, hash );
sph_gost512( &ctx.gost, hash, 64 );
sph_gost512_close( &ctx.gost, hash );
memcpy(output, hash, 32);
}
int scanhash_skunk( int thr_id, struct work *work, uint32_t max_nonce,
uint64_t *hashes_done )
{
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[19];
uint32_t _ALIGN(64) endiandata[20];
uint32_t nonce = first_nonce;
volatile uint8_t *restart = &(work_restart[thr_id].restart);
if ( opt_benchmark )
((uint32_t*)ptarget)[7] = 0x0cff;
for ( int k = 0; k < 19; k++ )
be32enc( &endiandata[k], pdata[k] );
// precalc midstate
sph_skein512_init( &skunk_ctx.skein );
sph_skein512( &skunk_ctx.skein, endiandata, 64 );
const uint32_t Htarg = ptarget[7];
do
{
uint32_t hash[8];
be32enc( &endiandata[19], nonce );
skunkhash( hash, endiandata );
if ( hash[7] <= Htarg && fulltest( hash, ptarget ) )
{
pdata[19] = nonce;
*hashes_done = pdata[19] - first_nonce;
return 1;
}
nonce++;
} while ( nonce < max_nonce && !(*restart) );
pdata[19] = nonce;
*hashes_done = pdata[19] - first_nonce + 1;
return 0;
}
bool skunk_thread_init()
{
sph_skein512_init( &skunk_ctx.skein );
cubehashInit( &skunk_ctx.cube, 512, 16, 32 );
sph_fugue512_init( &skunk_ctx.fugue );
sph_gost512_init( &skunk_ctx.gost );
return true;
}
bool register_skunk_algo( algo_gate_t* gate )
{
gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | AVX2_OPT;
gate->miner_thread_init = (void*)&skunk_thread_init;
gate->scanhash = (void*)&scanhash_skunk;
gate->hash = (void*)&skunkhash;
return true;
}

View File

@@ -24,19 +24,7 @@ typedef struct {
#endif #endif
} tribus_ctx_holder; } tribus_ctx_holder;
tribus_ctx_holder tribus_ctx; static __thread tribus_ctx_holder tribus_ctx;
void init_tribus_ctx()
{
sph_jh512_init( &tribus_ctx.jh );
sph_keccak512_init( &tribus_ctx.keccak );
#ifdef NO_AES_NI
sph_echo512_init( &tribus_ctx.echo );
#else
init_echo( &tribus_ctx.echo, 512 );
#endif
}
void tribus_hash(void *state, const void *input) void tribus_hash(void *state, const void *input)
{ {
@@ -44,7 +32,7 @@ void tribus_hash(void *state, const void *input)
tribus_ctx_holder ctx; tribus_ctx_holder ctx;
memcpy( &ctx, &tribus_ctx, sizeof(tribus_ctx) ); memcpy( &ctx, &tribus_ctx, sizeof(tribus_ctx) );
sph_jh512( &ctx.jh, input, 80 ); sph_jh512( &ctx.jh, input+64, 16 );
sph_jh512_close( &ctx.jh, (void*) hash ); sph_jh512_close( &ctx.jh, (void*) hash );
sph_keccak512( &ctx.keccak, (const void*) hash, 64 ); sph_keccak512( &ctx.keccak, (const void*) hash, 64 );
@@ -93,6 +81,10 @@ int scanhash_tribus(int thr_id, struct work *work, uint32_t max_nonce, uint64_t
be32enc(&endiandata[i], pdata[i]); be32enc(&endiandata[i], pdata[i]);
} }
// precalc midstate
sph_jh512_init( &tribus_ctx.jh );
sph_jh512( &tribus_ctx.jh, endiandata, 64 );
#ifdef DEBUG_ALGO #ifdef DEBUG_ALGO
printf("[%d] Htarg=%X\n", thr_id, Htarg); printf("[%d] Htarg=%X\n", thr_id, Htarg);
#endif #endif
@@ -131,9 +123,21 @@ int scanhash_tribus(int thr_id, struct work *work, uint32_t max_nonce, uint64_t
return 0; return 0;
} }
bool tribus_thread_init()
{
sph_jh512_init( &tribus_ctx.jh );
sph_keccak512_init( &tribus_ctx.keccak );
#ifdef NO_AES_NI
sph_echo512_init( &tribus_ctx.echo );
#else
init_echo( &tribus_ctx.echo, 512 );
#endif
return true;
}
bool register_tribus_algo( algo_gate_t* gate ) bool register_tribus_algo( algo_gate_t* gate )
{ {
init_tribus_ctx(); gate->miner_thread_init = (void*)&tribus_thread_init;
gate->optimizations = SSE2_OPT | AES_OPT; gate->optimizations = SSE2_OPT | AES_OPT;
gate->get_max64 = (void*)&get_max64_0x1ffff; gate->get_max64 = (void*)&get_max64_0x1ffff;
gate->scanhash = (void*)&scanhash_tribus; gate->scanhash = (void*)&scanhash_tribus;

20
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for cpuminer-opt 3.6.6. # Generated by GNU Autoconf 2.69 for cpuminer-opt 3.6.7.
# #
# #
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='cpuminer-opt' PACKAGE_NAME='cpuminer-opt'
PACKAGE_TARNAME='cpuminer-opt' PACKAGE_TARNAME='cpuminer-opt'
PACKAGE_VERSION='3.6.6' PACKAGE_VERSION='3.6.7'
PACKAGE_STRING='cpuminer-opt 3.6.6' PACKAGE_STRING='cpuminer-opt 3.6.7'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
PACKAGE_URL='' PACKAGE_URL=''
@@ -1321,7 +1321,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures cpuminer-opt 3.6.6 to adapt to many kinds of systems. \`configure' configures cpuminer-opt 3.6.7 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1392,7 +1392,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of cpuminer-opt 3.6.6:";; short | recursive ) echo "Configuration of cpuminer-opt 3.6.7:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1497,7 +1497,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
cpuminer-opt configure 3.6.6 cpuminer-opt configure 3.6.7
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2000,7 +2000,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by cpuminer-opt $as_me 3.6.6, which was It was created by cpuminer-opt $as_me 3.6.7, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@@ -2981,7 +2981,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='cpuminer-opt' PACKAGE='cpuminer-opt'
VERSION='3.6.6' VERSION='3.6.7'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@@ -6677,7 +6677,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by cpuminer-opt $as_me 3.6.6, which was This file was extended by cpuminer-opt $as_me 3.6.7, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -6743,7 +6743,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
cpuminer-opt config.status 3.6.6 cpuminer-opt config.status 3.6.7
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@@ -1,4 +1,4 @@
AC_INIT([cpuminer-opt], [3.6.6]) AC_INIT([cpuminer-opt], [3.6.7])
AC_PREREQ([2.59c]) AC_PREREQ([2.59c])
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM

View File

@@ -518,7 +518,7 @@ enum algos {
ALGO_SHAVITE3, ALGO_SHAVITE3,
ALGO_SKEIN, ALGO_SKEIN,
ALGO_SKEIN2, ALGO_SKEIN2,
ALGO_S3, ALGO_SKUNK,
ALGO_TIMETRAVEL, ALGO_TIMETRAVEL,
ALGO_TIMETRAVEL10, ALGO_TIMETRAVEL10,
ALGO_TRIBUS, ALGO_TRIBUS,
@@ -583,7 +583,7 @@ static const char* const algo_names[] = {
"shavite3", "shavite3",
"skein", "skein",
"skein2", "skein2",
"s3", "skunk",
"timetravel", "timetravel",
"timetravel10", "timetravel10",
"tribus", "tribus",
@@ -703,6 +703,7 @@ Options:\n\
shavite3 Shavite3\n\ shavite3 Shavite3\n\
skein Skein+Sha (Skeincoin)\n\ skein Skein+Sha (Skeincoin)\n\
skein2 Double Skein (Woodcoin)\n\ skein2 Double Skein (Woodcoin)\n\
skunk Signatum (SIGT)\n\
timetravel timeravel8, Machinecoin (MAC)\n\ timetravel timeravel8, Machinecoin (MAC)\n\
timetravel10 Bitcore (BTX)\n\ timetravel10 Bitcore (BTX)\n\
tribus Denarius (DNR)\n\ tribus Denarius (DNR)\n\